Я сталкиваюсь с исключениями LazyLoading, такими как большинство людей, которые пытаются удалиться с ORM. В большинстве случаев переключение на желаемую выборку решает проблему (Lazy Loading/Non atomic queries/Thread safety/n + 1 problem...). Но у желающих выборки также есть недостатки, если вы имеете дело с действительно большим графом объектов.
Загрузка всего графа объектов не требуется в большинстве случаев использования. Мне плохо загружать больше необходимых данных (или загружать их из db и извлекать необходимое подмножество).
Итак, какие альтернативные способы решения этой проблемы (во время выполнения)?
Я видел:
- Ввести зависимость доступа к данным в объект домена и позволить объекту решить либо загрузить ленивый, либо нетерпеливый. Доменный уровень должен быть независимым от любой службы. Доменная инъекция также является дорогостоящей операцией. Домен должен быть недоступен для доступа к данным и должен использоваться с доступом или без доступа к данным.
- Извлеките все ленивые, за исключением случаев использования, которые требуют больше данных: это лучше для производительности, но это заставляет многих клиентов = > посещать серверы/базы данных. Инициализация ленивых полей также может страдать от боли (с JPA). Этот способ не является общим и относится к тем же ленивым ограничениям, о которых говорилось выше.
- Инкапсулировать настойчивость в классе Lazy: больше сложностей, нет лучшей практики для взаимодействия с ORM. Уровень вздутия сервисов (так много "написанного вручную" кода чувствует себя плохо).
- Используйте полные прогнозы для каждого прецедента: мы закончим с SQL и исключим преимущество ORM.
- Уровень DTO/Virtual Proxy обеспечивает большую сложность и упрощает работу с кодом (Wormhole antipattern → Bloat).
Я много думал о другом. Возможно, общий вариант white./black listning - это решение.
Идея (черный список): определение списка имен классов с границами для операции выборки. Если свойство соответствует и оно ленивое, удалите ленивый (CGLIB) прокси и заполните значение нулем. В противном случае, просто предотвратите выборку (и оставьте значение при нулевом значении). Поэтому мы можем установить четкие границы в наших DAO.
Пример: ProductDao.findByName("Soap",Boundaries.BLACKLIST,"Category, Discount")
два последних параметра также могут быть связаны с объектом Boundaries.
Идея (белый список): как черный список, но вы должны объявить свойства, которые должны быть загружены в белый список.
Что вы думаете о таком решении? (Возможные проблемы, ограничения, преимущества...) Как мне написать это в java? Может быть, через AOP, чтобы соответствовать методам DAO (потому что я могу модифицировать поведение прокси-сервера cglib)?