Java hibernate中的惰性集合初始化失败

Java hibernate中的惰性集合初始化失败,java,hibernate,collections,lazy-initialization,Java,Hibernate,Collections,Lazy Initialization,今天我在hibernate中遇到了下一个问题: 我的方法: @Transactional public Period getDefault(Team team) { Period defaultPeriod = team.getDefaultPeriod(); List<Period> periods = _periodDAO.getPeriods(team); if (!periods.contains(defaultPeriod)) {

今天我在hibernate中遇到了下一个问题:

我的方法:

@Transactional
public Period getDefault(Team team) {
    Period defaultPeriod = team.getDefaultPeriod();
    List<Period> periods = _periodDAO.getPeriods(team);
        if (!periods.contains(defaultPeriod)) {
            defaultPeriod = periods.get(periods.size() - 1);
        }
    }
    _periodDAO.initializeIssues(defaultPeriod);
    return defaultPeriod;
}
如果集合periods包含defaultPeriod

Caused by: org.hibernate.HibernateException: collection is not associated with any session
at org.hibernate.collection.AbstractPersistentCollection.forceInitialization(AbstractPersistentCollection.java:474)
at org.hibernate.Hibernate.initialize(Hibernate.java:417)
但如果我删除一些行并将方法更改为

@Transactional    
public Period getDefault(Team team) {
    Period defaultPeriod = team.getDefaultPeriod();
    _periodDAO.initializeIssues(defaultPeriod);
    return defaultPeriod;
}
它很好用

我调试了第一个示例,在整个方法过程中,hibernate会话并没有关闭

据我所知,如果会话中加载的对象(时段中的一个元素)具有与活动会话关联且存在于对象(defaultPeriod)之前的集合(defaultPeriod)也具有相同的关联,则(defaultPeriod)将失去其关联

这是真的吗?还有谁面临同样的问题


谢谢您的回答。

您的
团队
参数可能来自另一个事务和另一个Hibernate
会话

@Transactional
方法返回时,
TransactionManager
关闭执行一些清理的
会话
,并取消(设置为
null
)所有
PersistentCollection
实例的
会话
字段。您的
defaultPeriod
在其
issues
字段中有一个

Hibernate的
Hibernate.initialize()
强制初始化惰性的
PersistentCollection
,但有以下代码(调用
AbstractPersistentCollection#forceInitialization()

如果计划在原始
@Transactional
方法(生成
团队
的代码)之外使用
问题
集合,则需要加载底层对象。将其更改为“快速加载”,或者使用
Hibernate.initialize()
执行您正在执行的操作

另一个解决方案是使
会话的持续时间长于第一个
@Transactional
会话的持续时间,但我没有这方面的详细信息。快速的谷歌搜索应该会带来一些选择


这就是正在发生的事情

Period defaultPeriod = team.getDefaultPeriod();
获取id为(例如)的
期间
对象
42
。因为它发生在另一个已关闭的
会话
中,因此
问题
是一个
持久集合
,它有一个
null
会话
引用,并将抛出您得到的
异常

你这样做的原因是什么

List<Period> periods = _periodDAO.getPeriods(team);

不会被处决。虽然
equals()
返回
true
contains()
也返回
true
,并由于
而变为
false
),但对象并不相同。
列表中的on具有附加的(非空)
会话
,因此可以初始化会话。但是你的,
defaultPeriod
持有的不能

谢谢大家!!但是TransactionManager仅当时段包含defaultPeriod时才将defaultPeriod中问题的会话字段设置为空,否则-问题将很好地初始化。@OleksandrZ我想看看您的
equals()
方法,用于比较
时段的实例。虽然
Periods
可能包含它,但集合中的一个附加到
会话
,而外部的一个则不是。equals方法非常简单,并且基于对时段id的比较。我可以初始化defaultPeriod的问题,只要我不再从db检索此实体,因此,如果我更改代码并添加句点defaultPeriod2=_periodAO.get(defaultPeriod.getId());将不会再次初始化问题,而不是检索期间。谢谢,谢谢!在我的问题中,我没有使用@Transactional作为另一种方法getDefault。很抱歉因此,据我所知,只有在使用query to db时才会创建新事务,而不是初始化现有集合。在
@Transactional
中发生的任何事情都将发生在Hibernate
会话中,在
事务中。当该方法返回时,根据配置,将提交
事务
,并关闭
会话
。只有当
会话
尚未关闭时,才能初始化集合。我认为它不一定必须在同一个
事务中。
Period defaultPeriod = team.getDefaultPeriod();
List<Period> periods = _periodDAO.getPeriods(team);
   if (!periods.contains(defaultPeriod)) {
        defaultPeriod = periods.get(periods.size() - 1);
   }