java - 延迟获取中的奇怪 session 错误

标签 java hibernate spring transactions

错误是未能延迟初始化集合,没有 session 或 session 已关闭

有很多人问了几乎相同的问题,但解决方案并不那么直观。而且,我认为有必要发布另一个问题来描述奇怪的错误消息:

(我不打算在这里粘贴源代码,因为它太长了。)

DEBUG [main] (AbstractPlatformTransactionManager.java:365) - Creating new transaction with name [com.bee32.plover.orm.feaCat.FeaturePlayer.tcList]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
DEBUG [main] (HibernateTransactionManager.java:493) - Opened new Session [org.hibernate.impl.SessionImpl@19006c9] for Hibernate transaction
DEBUG [main] (HibernateTransactionManager.java:523) - Not preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@19006c9]
DEBUG [main] (HibernateTemplate.java:397) - Found thread-bound Session for HibernateTemplate
Hibernate:    /* criteria query */ select 
    ...

ERROR [main] (LazyInitializationException.java:42) - failed to lazily initialize a collection, no session or session was closed
org.hibernate.LazyInitializationException: failed to lazily initialize a collection, no session or session was closed
  at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:380)
    ...
  at java.util.HashSet.<init>(HashSet.java:116)
    ...
  at org.hibernate.loader.Loader.list(Loader.java:2124)
    ...
  at org.springframework.orm.hibernate3.HibernateTemplate$5.doInHibernate(HibernateTemplate.java:590)
  ...

DEBUG [main] (HibernateTemplate.java:422) - Not closing pre-bound Hibernate Session after HibernateTemplate
DEBUG [main] (AbstractPlatformTransactionManager.java:843) - Initiating transaction rollback
DEBUG [main] (HibernateTransactionManager.java:672) - Rolling back Hibernate transaction on Session [org.hibernate.impl.SessionImpl@19006c9]
DEBUG [main] (HibernateTransactionManager.java:734) - Closing Hibernate Session [org.hibernate.impl.SessionImpl@19006c9] after transaction

如你所见,当lazy-fetch被触发时,错误发生了,已经有一个thread-bound session,直到事务回滚才关闭。

那么,为什么它报告没有 session 或 session 已关闭

编辑 相关来源:

@Transactional
public void tcList() {
    for (Cat cat : dao.list()) {
        System.out.println("Saved cat: " + cat);
    }
}

最佳答案

线程绑定(bind)了一个session,但是catList是否被这个session管理? session 可能已在 dao.list() 中由处理样板代码的 hibernate 模板关闭。

解决问题的一种方法是在返回列表之前调用 dao.list() 函数中的 list.get(0).someGetter()。这将用实际值填充列表,并且不应导致延迟初始化异常。如果 Cat 由其他延迟初始化的对象组成,您也应该对它们调用 getter 属性,以防您想使用这些属性。

此外,尝试删除 dao.list() 方法上的任何事务注释(如果有)。使用调用函数创建的事务,而不是使用 Propagation_Required 属性。如果您在 dao.list() 上使用了 @Transactional,事务管理器可能会在从此函数返回时触发 transaction.commit()/session.close(),因此 catList 成为一个分离的实体,其中所有的猫都是仍然是代理。

关于java - 延迟获取中的奇怪 session 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5342482/

相关文章:

java - hibernate transient 成员的默认值

java - 如何在 hibernate 注释类中将两列作为主键

java - 在 Spring-Boot 中为 soap webservice 抛出自定义异常?

java - 在 iText 7 中附加 2 个表格

java - 使用spring data 1.4.1.RELEASE的MongoDB 3.0连接和认证

java - 在 JList 上设置透明背景

java - 具有 Kerberos 身份验证的 PCF Kafka - 在本地运行但在 PCF 中失败

java - 更改 NavigationView 中项目的样式

java - 没有轮询的 Mule 文件连接器

java - hibernate中的单表策略继承