Когда нужен lazy loading связаных сущностей в Hibertate?

249
28 июля 2017, 00:59

Есть несколько связанных сущностей. У сущности Propose в виде поля есть User. И связаны они таким образом:

<class name="ru.pravvich.model.Propose" table="propose">
    <id name="id" column="id" type="integer">
        <generator class="identity"/>
    </id>
    <property name="sold" column="sold"/>
    <property name="description" column="description"/>
    <property name="mark" column="mark"/>
    <property name="model" column="model"/>
    <many-to-one name="auhtor"
                 column ="id_auhtor"
                 class="ru.pravvich.model.User">
    </many-to-one>
</class>

При выгрузке данных все время возникают проблемы с подгрузкой User так как транзакция еще не закончилась но и User еще не выгрузился из базы. К примеру вот такой кусочек DAO к которому происходит обращение из сервлетов:

private final AtomicReference<SessionFactory> factory;
public Propose getProposeId(final int id) {
    Propose result;
    try (final Session session = factory.get().openSession()) {
        session.beginTransaction();
        result = session.get(Propose.class, id);
    }
    return result;
} 

И тут встает плохой выбор: Либо я ловлю LazyInitializationException и так и не получаю данные User'a, либо я должен оставить сессию открытой, что тоже плохо так как вообще не понятно кто и когда ее будет закрывать.

В связи с этим 2 связанных между собой вопросов:

1. Как понять нужна ли вообще включенная lazy загрузка? И не лучше ли добавлять в конфигурацию lazy="false" и закрыть проблему?

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

И вопрос в том: когда и как закрывать сессию? Неужели просто бросить ее открытой в расчете что в конце работы приложения у SessionFactory будет вызван close() и это все решит? Не будут ли эти открытые сессии накапливаться и создавать проблемы? Как это решается в типовых случаях?

Answer 1

В случае с many-to-one ленивая загрузка скорее не нужна. В JPA 2.0 это отношение по умолчанию жадное. А вот one-to-many наоборот ленивое. Представьте, что у вас есть код, который должен показать только ФИО какого-то User из базы. Но с этим User связано, предположим, 10 000 Propose. В случае жадной загрузки, вы основательно нагрузите СУБД выборкой данных, которые вам не нужны. Поэтому пользоваться ленивой загрузкой или нет и как именно пользоваться зависит от конкретной ситуации. Совет на все случаи жизни тут просто невозможен.

READ ALSO
Что такое JavaTexField [требует правки]

Что такое JavaTexField [требует правки]

напишите пример JTextField пожалуйстаJava

277
Как внедрить свою реализацию бд в Openfire?

Как внедрить свою реализацию бд в Openfire?

Здравствуйте, подскажите, пожалуйста, открыл для себя новый протокол XMPPВ частности начал изучать реализующей его Openfire

261
Не запускается проект в Android Studio

Не запускается проект в Android Studio

После переустановки Android Studio стала недоступна кнопка "run" для старых проектов Что делать?

339