Я обычно использую Hibernate в сочетании с Spring каркасом и декларативной демаркацией транзакций (например, @Transactional).
Как мы все знаем, hibernate пытается быть неинвазивным и прозрачным, однако это доказывает немного сложнее при использовании lazy-loaded.
Я вижу ряд альтернатив дизайна с различными уровнями прозрачности.
- Сделать отношения не ленивыми (например,
fetchType=FetchType.EAGER)- Это vioalites всей идеей ленивой загрузки.
- Инициализировать коллекции с помощью
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)