Элемент поля Hibernate Path - исключение ленивой загрузки [дубликат]

Добавить AddType application/x-httpd-php .php в файл httpd.conf, если вы используете Apache 2.4

120
задан Rubens Mariuzzo 6 February 2015 в 17:54
поделиться

17 ответов

Неправильно здесь то, что ваша конфигурация управления сеансом настроена на закрытие сеанса при совершении транзакции. Проверьте, есть ли у вас что-то вроде:

<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 в запросе, только пару строк выше.

Некоторое чтение:

заводская конфигурация сеанса

проблема с закрытой сессией

60
ответ дан goroncy 21 August 2018 в 08:38
поделиться
  • 1
    Спасибо! Я решил проблему, используя openSession () вместо getCurrentSession (), поскольку одна из ссылок, которые вы мне дали, предложила это, но теперь я боюсь, если это неправильно делать – Blerta Dhimitri 5 February 2014 в 13:39
  • 2
    Нет, это, наверное, хорошо. Но прочитайте еще кое-что, чтобы иметь возможность полностью контролировать свои сеансы и транзакции. Очень важно знать основы, потому что все технологии более высокого уровня, такие как Spring, Hibernate и другие, работают по одной и той же концепции. – goroncy 5 February 2014 в 14:08

Я получал ту же ошибку для одного-многих отношений для ниже аннотации.

@OneToMany(mappedBy="department", cascade = CascadeType.ALL)

Изменен как ниже после добавления fetch = FetchType.EAGER, он работал для меня.

@OneToMany(mappedBy="department", cascade = CascadeType.ALL, fetch=FetchType.EAGER)
6
ответ дан Ahmed Ashour 21 August 2018 в 08:38
поделиться
  • 1
    Да, это может исправить, но теперь вы загружаете все дерево данных. В большинстве случаев это негативно скажется на производительности – astro8891 11 June 2018 в 01:39

использует session.get (*. class, id); но не загружать функцию

-1
ответ дан Artavazd Manukyan 21 August 2018 в 08:38
поделиться

Выполните следующие изменения в 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>
-3
ответ дан ArunDhwaj IIITH 21 August 2018 в 08:38
поделиться

Вы можете попробовать установить

<property name="hibernate.enable_lazy_load_no_trans">true</property>

в файле hibernate.cfg.xml или persistence.xml

. Проблема с этим свойством хорошо объясняется здесь

91
ответ дан Community 21 August 2018 в 08:38
поделиться

Это исключение из-за того, что вы вызываете session.getEntityById(), сеанс будет закрыт. Поэтому вам необходимо повторно привязать объект к сеансу. Или простое решение просто настроит default-lazy="false" на ваш entity.hbm.xml, или если вы используете аннотации, просто добавьте @Proxy(lazy=false) в свой класс сущностей.

5
ответ дан Garf365 21 August 2018 в 08:38
поделиться

Здесь есть несколько хороших ответов, которые обрабатывают эту ошибку в широком диапазоне. Я столкнулся с конкретной ситуацией с Spring Security, которая быстро, хотя, вероятно, и не была оптимальной, исправлена.

Во время авторизации пользователя (сразу после входа в систему и прохождения аутентификации) я тестировал пользовательский объект для определенного органа в пользовательском классе, который расширяет SimpleUrlAuthenticationSuccessHandler.

Мой пользовательский объект реализует UserDetails и имеет набор ленивых загруженных Ролей, которые бросали исключение «org.hibernate.LazyInitializationException», не могли инициализировать исключение прокси - без сеанса. Изменение этого набора из «fetch = FetchType.LAZY» на «fetch = FetchType.EAGER» исправило это для меня.

2
ответ дан Night Owl 21 August 2018 в 08:38
поделиться

Это означает, что объект, к которому вы пытаетесь получить доступ, не загружен, поэтому напишите запрос, который делает попытку соединения объекта, к которому вы пытаетесь получить доступ.

Например:

Если вы пытаетесь получить ObjectB из ObjectA, где ObjectB является внешним ключом в ObjectA.

Запрос:

SELECT objA FROM ObjectA obj JOIN FETCH obj.objectB objB
0
ответ дан rex roy 21 August 2018 в 08:38
поделиться

вы также могли бы решить это, добавив lazy = false в ваш * .hbm.xml-файл или вы можете запустить свой объект в Hibernate.init (Object), когда вы получите объект из db

-3
ответ дан Sandeep Roniyaar 21 August 2018 в 08:38
поделиться
  • 1
    обычно добавление lazy = false не является хорошей идеей. поэтому по умолчанию лень – MoienGK 6 November 2014 в 12:51
  • 2
    OP явно заранее заявила, что ему не разрешено это делать. – GingerHead 19 May 2015 в 16:09

, если вы используете данные весны jpa, весеннюю загрузку, вы можете добавить эту строку в application.properties

spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
3
ответ дан Shaaban Ebrahim 21 August 2018 в 08:38
поделиться

Я столкнулся с той же проблемой. Я думаю, что еще один способ исправить это состоит в том, что вы можете изменить запрос, чтобы присоединиться к извлечению вашего элемента из модели следующим образом:

Query query = session.createQuery("from Model m join fetch m.element where modelGroup.id = :modelGroupId")
4
ответ дан Tony Vu 21 August 2018 в 08:38
поделиться

Если вы используете Spring, отметьте класс как @Transactional , тогда Spring будет обрабатывать управление сеансом.

@Transactional
public class My Class {
    ...
}

Используя @Transactional, многие важные аспекты, такие как транзакция распространение происходит автоматически. В этом случае, если вызывается другой метод транзакции, метод будет иметь возможность присоединиться к текущей транзакции, избегая исключения «no session».

63
ответ дан user2601995 21 August 2018 в 08:38
поделиться
  • 1
    Я не могу преувеличивать важность этого ответа. Я бы порекомендовал сначала попробовать этот вариант. – Spider 29 July 2016 в 16:19
  • 2
    Также обратите внимание, что для включения транзакций необходимо добавить @EnableTransactionManagement в свою конфигурацию. & quot; , если вызывается другой метод транзакции, метод будет иметь возможность присоединения к текущей транзакции & quot; это поведение отличается для разных способов осуществления транзакций, то есть прокси-сервера через прокси-сервер или слияние AspectJ. Обратитесь к документации . – Erik Hofer 25 August 2016 в 11:30
  • 3
    Не работал для меня. – Monkey Supersonic 4 May 2017 в 14:55
  • 4
    работает для меня, но я не уверен, что? – Robbo_UK 18 January 2018 в 15:13
  • 5
    Должны ли мы понимать аннотацию Spring 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.

33
ответ дан Vlad Mihalcea 21 August 2018 в 08:38
поделиться
  • 1
    Как определить, какой вызов вызывает проблему? Мне сложно определить вызов. Там в любом случае ? Для целей тестирования я использовал FetchType=EAGER, но это неправильное решение, верно? – Shantaram Tupe 22 November 2017 в 08:25
  • 2
    Просто используйте журнал. И EAGER плох, да. – Vlad Mihalcea 22 November 2017 в 12:56
  • 3
    спасибо, но проблема в стороне зрения, то есть JSP – Shantaram Tupe 22 November 2017 в 13:12
  • 4
    Затем вы должны использовать либо DTO, либо инициализировать все ассоциации, прежде чем покинуть службу @Transactional. – Vlad Mihalcea 22 November 2017 в 13:26
  • 5
    Мы должны выступать за лучшую корпоративную практику, но не за быстрое решение. – etlds 22 February 2018 в 18:08

Если вы используете JPQL, используйте JOIN FETCH - это самый простой способ: http://www.objectdb.com/java/jpa/query/jpql/from#LEFT_OUTER_INNER_JOIN_FETCH_

1
ответ дан xihui 21 August 2018 в 08:38
поделиться

Если вы используете Grail's Framework, просто разрешить ленивое исключение инициализации с помощью ключевого слова Lazy в определенном поле в классе домена.

Пример:

class Book {
    static belongsTo = [author: Author]
    static mapping = {
        author lazy: false
    }
}

Найти дополнительную информацию здесь

0
ответ дан Zeb 21 August 2018 в 08:38
поделиться
0
ответ дан Ab Sin 1 November 2018 в 03:20
поделиться
0
ответ дан Aman Goel 1 November 2018 в 03:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: