Добавить AddType application/x-httpd-php .php
в файл httpd.conf, если вы используете Apache 2.4
Неправильно здесь то, что ваша конфигурация управления сеансом настроена на закрытие сеанса при совершении транзакции. Проверьте, есть ли у вас что-то вроде:
<property name="current_session_context_class">thread</property>
в вашей конфигурации.
Чтобы преодолеть эту проблему, вы можете изменить конфигурацию фабрики сеансов или открыть другой сеанс и только спросить для тех ленивых загруженных объектов. Но я бы предложил здесь инициализировать эту ленивую коллекцию в самой getModelByModelGroup и вызвать:
Hibernate.initialize(subProcessModel.getElement());
, когда вы все еще в активном сеансе.
И последнее. Дружелюбный совет. У вас есть что-то вроде этого в вашем методе:
for (Model m : modelList)
if (m.getModelType().getId() == 3) {
model = m;
break;
}
Пожалуйста, установите этот код, просто отфильтруйте эти модели с идентификатором типа, равным 3 в запросе, только пару строк выше.
Некоторое чтение:
Я получал ту же ошибку для одного-многих отношений для ниже аннотации.
@OneToMany(mappedBy="department", cascade = CascadeType.ALL)
Изменен как ниже после добавления fetch = FetchType.EAGER, он работал для меня.
@OneToMany(mappedBy="department", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
использует session.get (*. class, id); но не загружать функцию
Выполните следующие изменения в servlet-context.xml
<beans:property name="hibernateProperties">
<beans:props>
<beans:prop key="hibernate.enable_lazy_load_no_trans">true</beans:prop>
</beans:props>
</beans:property>
Вы можете попробовать установить
<property name="hibernate.enable_lazy_load_no_trans">true</property>
в файле hibernate.cfg.xml или persistence.xml
. Проблема с этим свойством хорошо объясняется здесь
<property name="hibernate.enable_lazy_load_no_trans" value="true"/>
– ACV
24 August 2016 в 19:15
hibernate.enable_lazy_load_no_trans
является Anti-Patterns , правильно?
– Vlad Mihalcea
13 September 2016 в 08:13
Это исключение из-за того, что вы вызываете session.getEntityById()
, сеанс будет закрыт. Поэтому вам необходимо повторно привязать объект к сеансу. Или простое решение просто настроит default-lazy="false"
на ваш entity.hbm.xml
, или если вы используете аннотации, просто добавьте @Proxy(lazy=false)
в свой класс сущностей.
Здесь есть несколько хороших ответов, которые обрабатывают эту ошибку в широком диапазоне. Я столкнулся с конкретной ситуацией с Spring Security, которая быстро, хотя, вероятно, и не была оптимальной, исправлена.
Во время авторизации пользователя (сразу после входа в систему и прохождения аутентификации) я тестировал пользовательский объект для определенного органа в пользовательском классе, который расширяет SimpleUrlAuthenticationSuccessHandler.
Мой пользовательский объект реализует UserDetails и имеет набор ленивых загруженных Ролей, которые бросали исключение «org.hibernate.LazyInitializationException», не могли инициализировать исключение прокси - без сеанса. Изменение этого набора из «fetch = FetchType.LAZY» на «fetch = FetchType.EAGER» исправило это для меня.
Это означает, что объект, к которому вы пытаетесь получить доступ, не загружен, поэтому напишите запрос, который делает попытку соединения объекта, к которому вы пытаетесь получить доступ.
Например:
Если вы пытаетесь получить ObjectB из ObjectA, где ObjectB является внешним ключом в ObjectA.
Запрос:
SELECT objA FROM ObjectA obj JOIN FETCH obj.objectB objB
вы также могли бы решить это, добавив lazy = false в ваш * .hbm.xml-файл или вы можете запустить свой объект в Hibernate.init (Object), когда вы получите объект из db
, если вы используете данные весны jpa, весеннюю загрузку, вы можете добавить эту строку в application.properties
spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
Я столкнулся с той же проблемой. Я думаю, что еще один способ исправить это состоит в том, что вы можете изменить запрос, чтобы присоединиться к извлечению вашего элемента из модели следующим образом:
Query query = session.createQuery("from Model m join fetch m.element where modelGroup.id = :modelGroupId")
Если вы используете Spring, отметьте класс как @Transactional , тогда Spring будет обрабатывать управление сеансом.
@Transactional
public class My Class {
...
}
Используя @Transactional
, многие важные аспекты, такие как транзакция распространение происходит автоматически. В этом случае, если вызывается другой метод транзакции, метод будет иметь возможность присоединиться к текущей транзакции, избегая исключения «no session».
@EnableTransactionManagement
в свою конфигурацию. & quot; , если вызывается другой метод транзакции, метод будет иметь возможность присоединения к текущей транзакции i> & quot; это поведение отличается для разных способов осуществления транзакций, то есть прокси-сервера через прокси-сервер или слияние AspectJ. Обратитесь к документации .
– Erik Hofer
25 August 2016 в 11:30
Transactional
, поэтому рекомендуется не только для модификации транзакций, но и для доступа только к одним?
– Stephane
28 May 2018 в 12:43
Лучший способ обработать LazyInitializationException
- использовать директиву JOIN FETCH
:
Query query = session.createQuery(
"from Model m " +
"join fetch m.modelType " +
"where modelGroup.id = :modelGroupId"
);
В любом случае НЕ используйте следующие Анти-Шаблоны, как предложено по некоторым ответам:
Иногда проекция DTO является лучшим выбором, чем выборка объектов, и таким образом вы не получите LazyInitializationException
.
FetchType=EAGER
, но это неправильное решение, верно?
– Shantaram Tupe
22 November 2017 в 08:25
@Transactional
.
– Vlad Mihalcea
22 November 2017 в 13:26
Если вы используете JPQL, используйте JOIN FETCH - это самый простой способ: http://www.objectdb.com/java/jpa/query/jpql/from#LEFT_OUTER_INNER_JOIN_FETCH_
Если вы используете Grail's
Framework, просто разрешить ленивое исключение инициализации с помощью ключевого слова Lazy
в определенном поле в классе домена.
Пример:
class Book {
static belongsTo = [author: Author]
static mapping = {
author lazy: false
}
}
Найти дополнительную информацию здесь