0

org.hibernate.LazyInitializationException:未能延迟初始化角色集合:com.t4bt.gov.persistence.entities.Experts.institutaionList,没有会话或会话已关闭

4

1 回答 1

3

您在问题(代码?)中提供的细节很少,因此它必须是关于延迟加载的通用答案。以后,如果您需要答案,请提供有关实际问题的具体信息,以及您尝试解决的问题的描述。

当您在会话关闭后(通常是在事务结束后)尝试访问延迟加载的属性时,会发生 LazyInitialization。延迟初始化的工作方式是当您获取对象时它不会获取延迟初始化的属性,但是当您实际尝试访问它时,Hibernate 会再次查询数据库以获取它。

以下会产生这样的错误:

public class Something {
    [...]
    @OneToMany(fetch = FetchType.LAZY)
    private List<SomethingElse> somethingElse;

    public List<SomethingElse> getSomethingElse() {
        return somethingElse;
    }
}

public class SomethingDao {
    @Inject
    private EntityManager em;

    @Transactional
    public Something getById(final Integer id) {
        return em.find(Something.class, id);
    }
}

public class SomethingService {
    @Inject
    private SomethingDao dao;

    public List<SomethingElse> getSomethingElseForSomething(final Integer somethingId) { 
        final Something something = dao.getById(somethingId);
        return something.getSomethingElse() //Throws LazyInitializationException
    }
}

这里事务(以及会话)只存在于 dao 类中。一旦离开 dao-method,会话就消失了。因此,当您尝试访问服务中的延迟加载属性时,当 Hibernates 尝试联系会话以检索它时,它将失败。

为了避免这种情况,有几种可能性。

  1. 将Something-class的注解改为@OneToMany(fetch = FetchType.EAGER) 属性不再延迟加载,所以不再有问题。
  2. 添加@Transactional到服务方法。然后调用getSomethingElse()将与获取Something对象在同一个事务中,并且在这样做时会话仍然是活动的。
  3. getSomethingElse()在 Dao 方法中添加调用。然后它将在离开 Dao 类(和事务)之前初始化属性(从数据库中获取),并且它将在事务之外可用,无需与会话通信即可检索它。
于 2013-04-06T12:23:50.470 回答