在尝试获取数据时,我得到了一个例外,懒惰(最后的例外)
//应用程序通过以下DAO获取数据。
public T findById(PK id) {
T result = getHibernateTemplate().get(this.type, id);
getHibernateTemplate().flush();
return result;
}
// Junit测试调用serviceX.getById
@Transactional
public SomeObject getById(int x){
return (SomeObject) aboveDao.findById(x);
}
//使用JUnit
SomeObject someObj = serviceX.getById(3);
someObj.getAnotherObject().y.equals("3"); //**Exception** at this line.
// SomeObject类具有以下属性。
@OneToMany(cascade = { CascadeType.ALL }, fetch = FetchType.LAZY)
private AnotherObject anotherObject;
当试图访问junit中的anotherObject时,我得到以下异常
方法已尝试+额外配置
我们使用spring注释TransactionManager。 < tx:注释驱动/>在配置文件中指定。
另外,我尝试在JUnit之上添加@Transaction(propagation = Propagation.REQUIRED),但这并没有解决问题。如果我运行该应用程序,它没有任何问题。
如何为JUnit解决此类问题?
org.hibernate.LazyInitializationException: failed to lazily initialize
a collection of role xxxxx , no session or session was closed
答案 0 :(得分:1)
这里发生了什么
SomeObject someObj = serviceX.getById(3); // @Transactional boundary, no more session
someObj.getAnotherObject().y.equals("3"); // session doesn't exist, can't fetch LAZY loaded object
由于您的AnotherObject
已被LAZY
提取,因此实际上并未加载getById()
方法。当Session
结束时,与之关联的@Transactional
就会丢失。当执行从getById()
返回时。因为不再有Session
,所以你会得到例外。
您可以将FetchType
更改为EAGER
。如果您要访问对象的该字段,则需要在Transaction
边界内对其进行初始化。
如果您某些需要anotherObject
,则可能的解决方案是创建一个@Transactional
方法,该方法调用getById
并急切地加载该对象。
@Transactional
public SomeObject eagerGetById(int x){
SomeObject obj = getById(x);
obj.getAnotherObject(); // will force loading the object
return obj;
}
无论何时需要急切加载对象,都要调用此方法。
答案 1 :(得分:0)