简体   繁体   中英

how can to resolve org.hibernate.LazyInitializationException?

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

You provide very little details in your question (code?), so it will have to be a generalized answer regarding lazy loading. In the future, if you want answers, please provide concrete information about the actual problem, as well as descriptions as to what you have tried to solve it.

A LazyInitialization occurs when you try to access a lazily loaded property after the session is closed (which is usually after the transaction has ended). The way lazy initalization works is that it doesn't fetch the lazily initialized properties when you fetch the object, but when you actually try to access it, Hibernate does another query to the database to fetch it.

The following would produce such an error:

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
    }
}

Here the transaction (and thus the session) only exists in the dao-class. Once leaving the dao-method, the session is gone. So, when you try to access a lazy-loaded property in the service, it will fail when Hibernates tries to contact the session in order to retrieve it.

To avoid this, there are several possibilities.

  1. Change the annotation of the Something-class to @OneToMany(fetch = FetchType.EAGER) The property is no longer lazy-loaded, so no more problems.
  2. Add @Transactional to Service-method. Then the call to getSomethingElse() would be in the same transaction as the fetching of the Something-object, and the session will still be alive when doing so.
  3. Add a call to getSomethingElse() in the Dao-method. Then it will initialize the property (fetch it from the database) before leaving the Dao-class (and the transaction), and it will be available outside the transaction, with no need to communicate with the session in order to retrieve it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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