繁体   English   中英

如何解决org.hibernate.LazyInitializationException?

[英]how can to resolve org.hibernate.LazyInitializationException?

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

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

当您在会话关闭后(通常是在事务结束之后)尝试访问延迟加载的属性时,就会发生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方法后,会话就消失了。 因此,当您尝试访问服务中的延迟加载属性时,当Hibernate尝试联系会话以检索它时,它将失败。

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

  1. 将Something类的批注更改为@OneToMany(fetch = FetchType.EAGER)该属性不再延迟加载,因此不再有问题。
  2. @Transactional添加到Service-method。 然后,对getSomethingElse()的调用将与获取Something对象的事务处于同一事务中,并且这样做时会话仍将保持活动状态。
  3. 在Dao方法中添加对getSomethingElse()的调用。 然后,它将在离开Dao类(和事务)之前初始化属性(从数据库中获取属性),并且该属性将在事务外部可用,而无需与会话进行通信即可检索它。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM