2

懒惰地尝试获取数据时出现异常(最后出现异常)

//应用程序通过以下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:annotation-driven /> 在配置文件中指定。

另外,我尝试在 JUnit 之上添加 @Transaction(propagation = Propagation.REQUIRED) ,但这并没有解决问题。如果我运行该应用程序,它可以正常工作。

如何为 JUnit 解决此类问题?

 org.hibernate.LazyInitializationException: failed to lazily initialize 
 a collection of role xxxxx , no session or session was closed
4

2 回答 2

2

这是发生的事情

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

因为你的AnotherObjectLAZY提取了,所以它实际上并没有被加载到getById()方法中。当结束时,Session它所关联的会丢失@Transactional,即。当执行从getById(). 因为不再有 a Session,所以你得到了异常。

您可以将您的更改FetchTypeEAGER. 如果你要去你的对象的那个字段,你需要在你的Transaction边界中初始化它。

如果您只在某些时候需要anotherObject,一个可能的解决方案是创建一个@Transactional方法来调用getById并急切地加载对象。

@Transactional
public SomeObject eagerGetById(int x){
    SomeObject obj = getById(x);
    obj.getAnotherObject(); // will force loading the object
    return obj;
}

每当您需要急切地加载对象时调用此方法。

于 2013-10-01T18:01:51.630 回答
0

这可能对您有用LazyInitilializationException

于 2013-10-01T18:03:44.563 回答