Я обычно использую Hibernate в сочетании со средой Spring и его возможностями декларативного разграничения транзакций (например, @Transactional ).
Как все мы знаем, спящий режим старается быть максимально неинвазивным и прозрачным , однако это оказывается немного сложнее при использовании lazy-loaded
отношений.
Я вижу несколько вариантов дизайна с разным уровнем прозрачности.
- Сделайте отношения не перегруженными ленивыми отношениями (например,
fetchType=FetchType.EAGER)
- Это нарушает всю идею отложенной загрузки.
- Инициализировать коллекции с помощью
Hibernate.initialize(proxyObj);
- Это подразумевает относительно высокую степень связи с DAO.
- Хотя мы можем определить интерфейс с помощью
initialize
, другие реализации не гарантируют предоставления каких-либо эквивалентов.
- Добавьте поведение транзакции к
Model
самим постоянным объектам (используя либо динамический прокси, либо@Transactional
)- Я не пробовал использовать динамический прокси-сервер, хотя мне никогда не удавалось заставить @Transactional работать с самими постоянными объектами. Вероятно, из-за этого спящий режим - это работа с прокси-сервером.
- Потеря контроля над фактическими транзакциями
- Предоставьте как ленивый, так и неленивый API, например,
loadData()
иloadDataWithDeps()
- Заставляет приложение знать, когда какую процедуру использовать, опять же жесткая связь
- Переполнение метода,,
loadDataWithA()
....,loadDataWithX()
- Принудительный поиск зависимостей, например, путем предоставления только
byId()
операций- Требуется много не объектно-ориентированных подпрограмм, например,,
findZzzById(zid)
а затемgetYyyIds(zid)
вместоz.getY()
- Может быть полезно получать каждый объект в коллекции по одному, если между транзакциями возникают большие накладные расходы на обработку.
- Требуется много не объектно-ориентированных подпрограмм, например,,
- Сделайте частью приложения @Transactional, а не только DAO
- Возможные аспекты вложенных транзакций
- Требуются процедуры, адаптированные для управления транзакциями (например, достаточно маленькие)
- Небольшое влияние на программу, хотя может привести к крупным транзакциям.
- Предоставьте DAO динамические профили выборки , например,
loadData(id, fetchProfile);
- Приложения должны знать, какой профиль использовать, когда
- Тип транзакций AoP, например, операции перехвата и выполнение транзакций при необходимости
- Требуется манипулирование байтовым кодом или использование прокси
- Потеря контроля при совершении транзакций
- Черная магия, как всегда :)
Я пропустил какой-нибудь вариант?
Какой подход вы предпочитаете, пытаясь свести к минимуму влияние lazy-loaded
взаимосвязей в дизайне приложения?
(Ой, извините за WoT )