Исправьте меня, если что-нибудь неправильно.
Теперь, когда мы применяем ДАО Spring для шаблонов ORM, когда мы используем атрибут @Transactional, мы не управляем транзакцией и/или сессией, когда метод называют внешне, не в рамках метода.
Ленивая загрузка сохраняет ресурсы - меньше запросов к дб, меньше памяти для хранения всех наборов выбранными в памяти приложения.
Так, если lazy=false, то все выбирается, все связанные наборы, который не является эффективно, если существует 10 000 записей в связанном наборе.
Теперь, у меня есть метод в классе ДАО, который, как предполагается, возвращает меня Пользовательский объект. Это имеет наборы, которые представляют связанные таблицы базы данных. Я должен получить объект идентификатором и затем запросить его наборы.
Будьте в спящем режиме "отказавшие для ленивой инициализации набора" исключение, происходит, когда я пытаюсь получить доступ к связанному набору, который возвращает этот метод ДАО.
Объясните, что такое обходное решение здесь?
Обновление: Хорошо, позвольте мне спросить Вас это. ДАО является абстрактным слоем, таким образом, метод "getUserById (Целочисленный идентификатор)", как предполагается, возвращает Объект.
Что, если в некоторых случаях мне нужны эти связанные наборы Пользовательского объекта и в другой ситуации, мне нужны те наборы.
Есть ли только два пути: 1) ленивая загрузка = ложь 2) создает различные методы: getUserByIdWithTheseCollections (), getUserByIdWithOtherCollections () и в тех методах используют Ваш подход?
Я имею в виду, там только 2 пути и ничто лучше?
Обновление 2: Объясните, что дало бы мне конкретный вид использования SESSIONFACTORY? Как это смотрит на практике? Мы создаем экземпляр объекта ДАО, затем вводим его с фабрикой сессии, и это означало бы, что два последовательных вызова метода ДАО будут работать в рамках той же транзакции? Мне кажется, что так или иначе, ДАО отсоединяется от классов, которые используют его!
Логика и транзакции инкапсулируются в ДАО, правильно?
Вы можете получить связанную коллекцию в транзакции, чтобы загрузить ее, находясь внутри транзакции:
User user = sessionFactory.getCurrentSession().get(User.class, userId);
user.getLinkedCollection().size();
return user;
Как отметил BalusC, вы можете использовать Hibernate.initialize()
вместо size()
. Это намного чище.
Затем, когда вы возвращаете такую сущность, ленивое поле уже инициализировано.
Отвечая на ваш PS - возможно ли использование транзакций на уровне сервиса (а не DAO)? Похоже, что да, поскольку выполнение каждого вызова DAO в отдельной транзакции кажется расточительством (и может быть некорректным).
Я считаю, что лучше всего разместить @Transactional на уровне сервиса, а не на уровне DAO. В противном случае все ваши вызовы DAO находятся в отдельных сеансах гибернации - все эти вещи о равенстве объектов не будут работать.