即使在 HQL 查询中使用 Join Fetch,Hibernate Lazy Initialization 异常
Hibernate Lazy Initialization exception even using Join Fetch in HQL queries
我想用延迟获取模式初始化一个集合并在我的查询中使用 Join Fetch 但我有时(并非总是)遇到延迟初始化异常 ???
org.hibernate.LazyInitializationException: failed to lazily initialize
a collection of role: xxx.entity.Product.producerEntities, could not
initilaize proxy - no session ...
例如这个查询:
"select p from Product p left join fetch p.producerEntities"
还有我的坚持class:
class Product
{
Set<Producer> producerEntities = new HashSet<>();
....
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name="pid")
public Set<Producer> getProducerEntities(){
return producerEntities;
}
....
}
我不明白这是什么问题?
如果 join fetch 抛出 LIEX,那么我建议使用动态实体图,因为如果您需要定义用例特定图。
让我们试试这个,我做了并且为我工作。
public class DynamicEntityGraphDemo {
public static void main(String[] args) {
EntityManager em = HibernateUtil.getEntityManager();
EntityGraph graph = em.createEntityGraph(Product.class);
Subgraph itemGraph = graph.addSubgraph("producerEntities");
Map hints = new HashMap();
hints.put("javax.persistence.loadgraph", graph);
Product pro = em.find(Product.class, 1, hints);
System.out.println("DynamicEntityGraphDemo pro = " + pro.toString() +
"producer = " + pro.getProducerEntities().toString());
}
}
注意:动态实体图在检索子实体时使用 LEFT OUTER JOIN。
(子图 itemGraph = graph.addSubgraph("producerEntities");)
加入获取p.producerEntities,而不是p.producer..
问题出在我的集合 setter 和 getter 方法名称中。解决了。
解决的方法很多,利用hibernate属性
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
return dataSource;
}
@Bean
public LocalSessionFactoryBean getSessionFactory() throws IOException {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(dataSource());
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.enable_lazy_load_no_trans", "true");
factoryBean.setHibernateProperties(hibernateProperties);
factoryBean.afterPropertiesSet();
return factoryBean;
}
@Bean
public HibernateTransactionManager getTransactionManager() throws IOException {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(getSessionFactory().getObject());
return transactionManager;
}
或者您可以使用
org.hibernate.annotations.@Proxy
@Entity
@Table(name = "ACTOR")
@Proxy(lazy = false)
public class Actor
我想用延迟获取模式初始化一个集合并在我的查询中使用 Join Fetch 但我有时(并非总是)遇到延迟初始化异常 ???
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: xxx.entity.Product.producerEntities, could not initilaize proxy - no session ...
例如这个查询:
"select p from Product p left join fetch p.producerEntities"
还有我的坚持class:
class Product
{
Set<Producer> producerEntities = new HashSet<>();
....
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name="pid")
public Set<Producer> getProducerEntities(){
return producerEntities;
}
....
}
我不明白这是什么问题?
如果 join fetch 抛出 LIEX,那么我建议使用动态实体图,因为如果您需要定义用例特定图。
让我们试试这个,我做了并且为我工作。
public class DynamicEntityGraphDemo {
public static void main(String[] args) {
EntityManager em = HibernateUtil.getEntityManager();
EntityGraph graph = em.createEntityGraph(Product.class);
Subgraph itemGraph = graph.addSubgraph("producerEntities");
Map hints = new HashMap();
hints.put("javax.persistence.loadgraph", graph);
Product pro = em.find(Product.class, 1, hints);
System.out.println("DynamicEntityGraphDemo pro = " + pro.toString() +
"producer = " + pro.getProducerEntities().toString());
}
}
注意:动态实体图在检索子实体时使用 LEFT OUTER JOIN。 (子图 itemGraph = graph.addSubgraph("producerEntities");)
加入获取p.producerEntities,而不是p.producer..
问题出在我的集合 setter 和 getter 方法名称中。解决了。
解决的方法很多,利用hibernate属性
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
return dataSource;
}
@Bean
public LocalSessionFactoryBean getSessionFactory() throws IOException {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(dataSource());
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.enable_lazy_load_no_trans", "true");
factoryBean.setHibernateProperties(hibernateProperties);
factoryBean.afterPropertiesSet();
return factoryBean;
}
@Bean
public HibernateTransactionManager getTransactionManager() throws IOException {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(getSessionFactory().getObject());
return transactionManager;
}
或者您可以使用
org.hibernate.annotations.@Proxy
@Entity
@Table(name = "ACTOR")
@Proxy(lazy = false)
public class Actor