- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有以下 hibernate 映射。
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "product")
private Set<ProductLicense> productLicenses = new HashSet<ProductLicense>(0);
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "product_id", nullable = false)
private Product product;
但是当我调用 product.getProductLicences() 时,我总是得到一个空的 Set,即使在事务方法中也是如此。
sessionFactory.getCurrentSession().get(Product.class, productId))
.getProductLicenses()
下面是ProductDaoImpl类
@Repository
public class ProductDaoImpl implments ProductDao{
@Autowired
private SessionFactory sessionFactory;
@Override
public Product getProduct(Integer productId)
{
Product result = (Product) sessionFactory.getCurrentSession().get(Product.class, productId);
Hibernate.initialize(result.getProductLicenses());
//sessionFactory.getCurrentSession().refresh(result);
return result;
}
.. other methods
}
此外,如果我调用 Hibernate.initialize(product);不执行表之间的任何连接。指令sessionFactory.getCurrentSession().get(Product.class, productId);不会对数据库产生任何查询(我的属性 show_sql 等于 true)。但是如果我取消注释 sessionFactory.getCurrentSession().refresh(result);我可以看到 sql 和集合已加载,但我不明白为什么在另一种情况下未加载。但是我不明白我的映射有什么问题。
产品类别是:
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "product_id", unique = true)
private Integer productId;
@NotNull
@Size(max = 200)
@Column(name = "name")
private String name;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "product")
private Set<ProductLicense> productLicenses = new HashSet<ProductLicense>(0);
public Set<ProductLicense> getProductLicenses()
{
return productLicenses;
}
public void setProductLicenses(Set<ProductLicense> productLicenses)
{
this.productLicenses = productLicenses;
}
//getters and setters
..
}
ProductLicense 类:
@Entity
@Table(name = "product_license")
public class ProductLicense {
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "product_license_id", unique = true)
private Integer productLicenseId;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "product_id", nullable = false)
private Product product;
@NotNull
@Column(name = "key")
private String key;
// getters and setters ...
}
最后我的配置如下:
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("com.company.package")
@PropertySource("classpath:application.properties")
public class WebAppConfig {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
@Resource
private Environment env;
@Bean
public DataSource dataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
private Properties hibProperties()
{
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL,
env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put("hibernate.cache.provider_class", "org.hibernate.cache.NoCacheProvider");
properties.put("hibernate.cache.use_second_level_cache", "false");
return properties;
}
@Bean
public LocalSessionFactoryBean sessionFactory()
{
LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean();
lsfb.setDataSource(this.dataSource());
lsfb.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
lsfb.setHibernateProperties(this.hibProperties());
return lsfb;
}
@Bean
public HibernateTransactionManager transactionManager()
{
return new HibernateTransactionManager(this.sessionFactory().getObject());
}
}
我的测试:
@Before
@Transactional
public void setUp() throws ParseException
{
product1 = new Product();
..
productService.addProduct(product1);
product2 = new Product();
..
product2 = productService.addProduct(product2);
productService.addProductLicense(product2.getProductId(), licenceKey1Product2);
productService.addProductLicense(product2.getProductId(), licenceKey2Product2);
}
@Test
@Transactional
public void addProductLicenseTest()
{
String licenseKey[] = { "thisisthekey", "thisisthekey2" };
productService.addProductLicense(product1.getProductId(), licenseKey[0]);
//sessionFactory.getCurrentSession().flush();
//sessionFactory.getCurrentSession().clear();
Product product1saved = productService.getProduct(product1.getProductId());
assertEquals(1, product1saved.getProductLicenses().size());
assertEquals(licenseKey[0], product1saved.getProductLicenses().iterator().next().getKey());
productService.addProductLicense(product1.getProductId(), licenseKey[1]);
product1saved = productService.getProduct(product1saved.getProductId());
assertEquals(2, product1saved.getProductLicenses().size());
}
最佳答案
这是(很可能)发生的事情。
您的整个测试方法都是事务性的。因此,服务调用与测试代码本身发生在同一事务中。
在测试中,您将在没有任何许可的情况下创建并保留一个产品。这将 Product 实例存储在 session 缓存中,与事务相关联。该产品的许可证列表为空。
然后您仍然在同一个事务中调用一个服务方法,该方法创建一个许可证,其产品是您之前创建的产品。我的猜测是此服务的代码如下所示:
Product product = (Product) session.get(Product.class, productId);
ProductLicense license = new ProductLicense();
license.setProduct(product);
session.persist(license);
在上面的代码中,产品是从 session 缓存中获取的,然后许可证与找到的产品一起保存。请注意,代码设置了许可证的产品,但没有将许可证添加到产品中,这就是问题所在。
然后您将通过 ID 获取产品,仍在同一笔交易中。因此,Hibernate 直接从缓存中检索产品。而在缓存中,由于您省略了向产品添加许可证,因此许可证列表仍然是空的。
因此,简而言之,您有责任维护双向关联的双方。如果您只初始化所有者端,Hibernate 将保留关联,并且如果它从数据库加载产品,将正确初始化列表。但是,当产品在缓存中时,它会保持在您将其存储在缓存中的状态。这就是您看到空列表的原因,除非您明确清除 session 并因此从数据库重新加载状态。
关于java - Hibernate 不会加载一对多的关系集,即使使用 eager fetch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22011757/
显然,可以实现 Haskell,使其在不改变语言语义的情况下急切地求值。如果这是真的,如何处理无限数据结构? http://csg.csail.mit.edu/pubs/haskell.html Th
有没有什么方法可以像@ManagedBean(eager=true ) 来自 javax.faces 包? @Named @ApplicationScoped public Mail() { ...
使用@ApplicationScoped @Named @Eager,我的@EJB注入(inject)的@Stateless bean未正确实例化并评估为空。 我有一个@ApplicationScop
我必须删除两个分隔符之间的字符串,即 从“123XabcX321”我想要“123321”。 对于一个简单的案例,我很好: $_=<>; s/X(.*)X//; print; 但是,如果像“123Xab
我有一个对象层次结构,订单,联系人,地址: public class Order { public virtual Contact BillingContact { get; set; }
Eager 模式仅支持 TF native 优化器我在以下尝试过的每个优化器中都会遇到此错误: def create_model(): model = tf.keras.models.Sequ
我有这样的数据设计:交易属于授权,而授权又属于客户。或者用结构体表示: type Transaction struct { shared.Transaction // transaction
我想在 Scheme 中做一个懒惰的列表。这是我到目前为止。 ;; Constructor for Pairs (define (cons-stream a b) (cons a (λ() b))
今天是个好日子 我是 Laravel 的新手,目前正在用它构建我的第一个简单的新闻应用程序 我有一个简单的查询,使用 laravel 的预先加载功能 但是在这个急切的加载功能中,我想根据某些条件获取某
我正在制作一个动态表单,让用户使用 vue.js 自动生成带有游戏统计信息的图像,并使用 Keen-ui。我是 vue.js 的新手,过去两周开始学习它。 现在,我在使用 eager-ui 进行选择下
我 fork 了 eager/dashboards github 存储库,并尝试创建一个 Dockerfile 以在 Docker 容器中运行仪表板。 我的 fork :https://github.
我的实体: @Entity @NoArgsConstructor public class Company { @Id @Getter @GeneratedValue(strategy =
在我的实体中,我必须使用 fetch = FetchType.EAGER 因为我有一个错误: nested exception is org.hibernate.LazyInitializationE
我在 Java 中使用 play 2.0.4。我正在尝试从 play 提供的内存数据库中保存和检索值(Ebean 是底层 JPA 实现)。下面是一些示例代码: @NoobDisclaimer ("I'
在 Pro .NET Performance - Optimize Your C# Applications 的第 96 页上,它谈到了 GC 急切根收集: For each local variab
我无法从数据库加载对象及其相对映射对象。可能我的“ map 系统”是错误的。 在数据库中保存对象(及其相对映射对象)时,一切正常,因此对象似乎已正确映射。 Utente是我的“主”对象 publ
我需要使用急切查询在 Laravel 中执行子查询,但结果始终为空。 查询: $project = Log::where('project_id', $id)->with(['log_occurenc
我有这个程序: var planetStream = require('../../'); var app = require('http').createServer(handler); var i
我需要与FetchType.EAGER(下面的示例)建立关系,但我有异常(exception)。如果我将 FetchType.EAGER 更改为 FetchType.LAZY 一切正常,但我确实需要
我正在使用 EF6 并尝试急切获取对象的整个结构。问题是我正在使用继承。 假设我有这个类(class)。 数据库上下文 DbSet A { get; set; } 示例类 public class A
我是一名优秀的程序员,十分优秀!