2013-04-06 8 views
0

org.hibernate.LazyInitializationException: не удалось инициализировать лениво набор ролей: com.t4bt.gov.persistence.entities.Experts.institutaionList, не сеанс или сеанс был закрытКак решить проблему org.hibernate.LazyInitializationException?

+0

возможно дубликат [org.hibernate.LazyInitializationException: Как правильно использовать ленивую функцию загрузки библиотеки Hibernate] (http://stackoverflow.com/questions/5837169/org-hibernate-lazyinitializationexception-how-to-properly-use -hibernates-ленивый) –

ответ

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-метода сеанс исчез. Поэтому, когда вы пытаетесь получить доступ к ленивому загружаемому свойству в службе, он не сработает, когда Hibernates попытается связаться с сеансом, чтобы получить его.

Чтобы избежать этого, существует несколько возможностей. не

  1. Изменения аннотации Something-класс @OneToMany(fetch = FetchType.EAGER) Свойства больше не лениво загружено, поэтому нет больше проблем.
  2. Добавить @Transactional в Сервис-метод. Тогда вызов getSomethingElse() будет в той же транзакции, что и выборка объекта Something, и при этом сеанс будет оставаться живым.
  3. Добавить вызов в getSomethingElse() в Дао-метод. Затем он инициализирует свойство (извлекает его из базы данных) перед тем, как покинуть Dao-класс (и транзакцию), и он будет доступен вне транзакции, без необходимости связываться с сеансом, чтобы получить его.
Смежные вопросы