2016-03-02 1 views
0
// This is what I have in my Model Class... 

    public class Quotation { 
    @JoinColumn(name = "party_id", referencedColumnName = "id") 
    @ManyToOne (fetch = FetchType.LAZY) 
    private Party party; 
    } 

И в моем контроллере я загрузке объекта цитаты, как это:Hibernate Ленивая загрузка не работает

// Load Quotation object by the Entity Manager:- em.find(Quotation.class, quoteId) 

    quotation = quotationService.getQuoteHeadById(quoteId); 
    log.debug(" party ID --> "+ quotation.getParty.getId()); 

Но я не получаю даже партийный идентификатор партии таблицы/объекта в этом ленивых Загрузка. Но если я изменю тип выборки на Eager, то log.debug() отлично меня доставит.

Я не прав ни на что ???

+0

try @ManyToOne (fetch = FetchType.LAZY, optional = false) –

+0

Можете ли вы предоставить код запроса? –

+0

@Eva Mariam: (fetch = FetchType.LAZY, optional = false) не решила проблему. – obsolete

ответ

0

Для получения полей LAZY вам необходимо находиться внутри транзакции. Ваш метод контроллера не является транснациональным. Получить представление от: Understanding transaction session with lazy loading in Spring JPA Hibernate

+0

Я только что объявил метод Transactional в ServiceImpl. Все еще имея ту же проблему ...... «не удалось инициализировать прокси - нет сеанса». ServiceImpl, как показано ниже: @Transactional (распространение = Propagation.SUPPORTS, только для чтения = истина) общественного цитаты getQuoteHeadById (Long quoteId) { \t возврата quotationDao.getQuoteHeadById (quoteId); \t} – obsolete

+0

ну, тогда нужно также проверить свою конфигурацию проекта. Транзакция должна настраиваться в контексте приложения должным образом. У вас есть ссылка github? –

+0

Нет брата У меня нет этого проекта в github.Но для справки, @Transaction поверх других необходимых методов работает нормально. Просто проблема в этом конкретном сценарии. – obsolete

0

Но я не получаю даже партийный идентификатор партии таблицы/объекта в это ленивая загрузка.

Ниже приведено поведение с @ManyToOne (fetch = FetchType.LAZY). Обратите внимание, что поведение отличается, когда мы используем аннотации hibernate для полей vs getters.

В классах сущностей вы используете hibernate annotations on the field. При этом, если вы вызываете даже метод getId(), как в quotation.getParty.getId() на объекте, он приводит к инициализации прокси-сервера (объекта-участника) и попадает в базу данных для его извлечения. Таким образом, транзакция должна быть активной, если не приведет к метанию lazyinitializationexception.

Если целью является только получение идентификатора объекта, вы можете разместить спящий режим annotations on the getter methods. Это не инициализирует прокси-сервер (объекта-участника) для возврата идентификатора и поэтому не требует активной транзакции. Но доступ к любому другому свойству, кроме id, потребует активной транзакции и приведет к попаданию в базу данных.

Посмотрите на соответствующих ошибки в HHH-3718

Таким образом, в вашем партии лица использовать свойство/геттер AccessType вместо доступа к полю. В качестве примера вместо

@Id 
@GeneratedValue(...) 
private long id; 

место их на добытчиках

@Id 
@GeneratedValue(...) 
public long getId() { ... } 

Убедитесь, что вы делаете подобные изменения в других областях Party лица. Вы можете позже изучить другой вариант использования @Access(AccessType.PROPERTY/FIELD) вместо этого, чтобы получить тот же эффект.

Переходя к EAGER

Но если изменить тип выборки нетерпеливым, то log.debug() дает мне идентификатор отлично.

Это происходит потому, что FetchType.EAGER приводит не извлечение сущности партии охотно (без прокси) фронта и поэтому мы можем получить идентификатор и другие свойства партии лица. Обратите внимание, что это приводит к запросу JOIN/extra SELECT на основе конфигурации.

Я не прав ни на что ???

Я не вижу здесь ничего плохого, и все это потому, что тип доступа типа vs getter имеет другое поведение. Таким образом, если вы используете доступ к файловому уровню, Hibernate инициализирует прокси-сервер даже для получения идентификатора связанного объекта в соответствии с bug HHH-3718 или до его разрешения.

и родственная тема на спящем форуме о поле против типа доступа собственности, которые могут представлять интерес Field Vs Property access

Надеются, что это ответ на ваш запрос.

+0

Не знаю, почему это было проголосовано. Предоставление причины поможет обновить ответ или исправить его соответствующим образом. –

+0

Я не отказался от этого, и знаю, что у меня еще нет репутации 15. Спасибо вам за вашу четкую картину. Я попробую. – obsolete

+0

@Backbencher Я понял. Кстати, было бы интересно узнать, помог ли мой ответ выше, почему ленивая загрузка не работает и как заставить ее работать? –

0

использовать это:

Hibernate.initialize (quotation.getParty());

0

Прежде всего установите транзакцию на уровне обслуживания. Затем настройте свойства спящего режима, такие как

<prop key="hibernate.enable_lazy_load_no_trans">true</prop> 

Я не знаю вашей конфигурации, но надеюсь, что это сработает. (Примечание: помните, что это может быть небезопасно)

2

Чтобы получить объект-участник из объекта цитаты, вам нужно использовать левую ссылку на выбор. Затем вы сможете получить доступ к вашему партийному объекту из объекта котировки.

Написать jpql запрос следующим образом:

SELECT q from Quotation q left join fetch q.party p 

Тогда вы не получите «не может инициализировать прокси - нет Session» ошибка. Кстати, это очень распространенная ошибка. Это означает, что вы пытаетесь получить доступ к объекту, который вы не получили по вашему запросу. Надеюсь, что этот ответ поможет.

+0

Это не сработало. И это на самом деле не тема Lazy loading, я думаю. Если я получаю объект Quotation, я должен получить идентификатор Party на ленивой загрузке с менеджером сущности спящего режима – obsolete

 Смежные вопросы

  • Нет связанных вопросов^_^