Я не уверен, на какую проблему (вызванную ленивостью) вы намекаете, но для меня самая большая боль - избегать потери контекста сеанса в моих собственных кешах приложений.Типичный случай:
- объект
foo
загружен и помещен в карту; - другой поток берет этот объект с карты и вызывает
foo.getBar()
(то, что раньше никогда не вызывалось)и оценивается лениво); - boom!
Итак, для решения этой проблемы у нас есть ряд правил:
- Обернуть сессии максимально прозрачно(например,
OpenSessionInViewFilter
для веб-приложений); - имеют общий API для потоков / пулов потоков, где привязка / разблокировка сеанса db выполняется где-то высоко в иерархии (в
try/finally
), поэтому подклассам не нужноподумайте об этом; - при передаче объектов между потоками передайте идентификаторы вместо самих объектов.Получающий поток может загрузить объект, если ему это необходимо;
- при кэшировании объектов, никогда не кэшируйте объекты, кроме их идентификаторов.Есть абстрактный метод в вашем DAO или классе менеджера для загрузки объекта из кэша Hibernate 2-го уровня, когда вы знаете идентификатор.Стоимость извлечения объектов из кэша Hibernate 2-го уровня все еще намного дешевле, чем переход в БД.
Это, как вы можете видеть, действительно далеко от неинвазивных и прозрачных .Но стоимость все еще терпима, если сравнивать с ценой, которую я должен был бы заплатить за готовую погрузку.Проблема с последним состоит в том, что иногда это приводит к эффекту бабочки при загрузке одного объекта, на который ссылаются, не говоря уже о коллекции объектов.Потребление памяти, использование ЦП и задержки, если не сказать больше, также намного хуже, так что, думаю, я смогу с этим смириться.