即使在 HQL 查询中使用 Join Fetch,休眠延迟初始化异常
Posted
技术标签:
【中文标题】即使在 HQL 查询中使用 Join Fetch,休眠延迟初始化异常【英文标题】:Hibernate Lazy Initialization exception even using Join Fetch in HQL queries 【发布时间】:2019-02-11 07:46:44 【问题描述】:我想用惰性获取模式初始化一个集合并在我的查询中使用 Join Fetch,但我有时(并非总是)遇到惰性初始化异常???
org.hibernate.LazyInitializationException: 延迟初始化失败 角色集合:xxx.entity.Product.producerEntities,不能 初始化代理 - 没有会话 ...
例如这个查询:
"select p from Product p left join fetch p.producerEntities"
还有我的持久性课程:
class Product
Set<Producer> producerEntities = new HashSet<>();
....
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name="pid")
public Set<Producer> getProducerEntities()
return producerEntities;
....
我不明白这是什么问题?
【问题讨论】:
@OneToMany 的默认获取类型是惰性的。 我知道 Angad Bansode,为了清楚起见,我写了 fetch = FetchType.LAZY。 您能否添加一个示例说明该异常何时发生?在Producer
中获取一些嵌套元素时会发生这种情况吗?
您可以使用动态实体图可能是更好的解决方案,如果您需要定义一个用例特定的图。如果加入提取不起作用。
【参考方案1】:
如果 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");)
【讨论】:
【参考方案2】:加入获取 p.producerEntities,而不是 p.producer..
【讨论】:
你是对的。这只是我的语法错误(大多数时候查询工作)。【参考方案3】:问题出在我的集合 setter 和 getter 方法名称上。解决了。
【讨论】:
您能否详细说明您必须更改的内容。【参考方案4】:有很多方法可以解决,使用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
【讨论】:
"hibernate.enable_lazy_load_no_trans" 被认为是一种反模式,就像使用 n+1 查询的急切加载一样。 FetchType.LAZY 和 JOIN FETCH 的全部意义在于解决这个问题。以上是关于即使在 HQL 查询中使用 Join Fetch,休眠延迟初始化异常的主要内容,如果未能解决你的问题,请参考以下文章