2012-06-06 8 views
3

Я сохраняю объекты спящего режима в ehcache. Когда вызов выполняется для слоя фасада для извлечения объекта, мой перехватчик будет вызывать этот метод и кэширует его. В следующий раз, когда вызывается тот же метод, объект будет возвращен из кеша. Все это прекрасно работает.Исключение Lazyinitialization при загрузке объекта hibernate из ehcache

У моего объекта есть некоторые свойства (объекты или связанные объекты), которые определены как FetchType.Lazy. Что-то вроде этого,

@JoinColumn(name = "inventory_item_oid", referencedColumnName = "inventory_item_oid") 
@ManyToOne(fetch = FetchType.LAZY) 
private InventoryItem inventoryItem; 

Следовательно, не все свойства загружены. Когда необходим элемент инвентаря, его вызывает. Этот вызов бросает исключение LazyInitialization.

Поскольку мои кешированные значения живут в течение одного дня, его можно вызвать любое количество раз, прежде чем оно истекло.

Один из этих вызовов, бросающий вышеуказанное исключение.

Я пришел, чтобы найти, что, используя длинные сеансы спящего режима, я могу решить эту проблему. Но это не работает, потому что мое приложение на основе запроса/ответа.

Есть еще один способ, когда мне нужно проверить, является ли InventoryItem нулевым или нет, прежде чем обращаться к его свойствам, если его значение равно null, тогда мне нужно получить это значение отдельно и прикрепить его к родительскому. Это кажется хорошим ... но требует много работы, поскольку у меня много объектов.

Я хотел бы знать, есть ли другой способ, который я могу получить для тех объектов, которые определены как ленивые.

ответ

1

Вы не должны кэшировать объекты в EHCache самостоятельно. Вместо этого вы должны настроить Hibernate для использования кэша второго уровня и использовать EHCache в качестве его реализации.

Конечный результат будет таким же: ваши объекты будут кэшироваться, и вы сохраните обратные вызовы в базу данных. Но, используя кеш второго уровня, все будет прозрачным: вы загрузите объекты из сеанса, а Hibernate автоматически сохранит их в кеше. И если вы перезагрузите их из сеанса, Hibernate выведет их из кеша. И если вы обновите объект, он будет выведен из кеша, чтобы в следующий раз перезагрузить новую копию.

Еще одна огромная разница с вашим решением ручной работы заключается в том, что Hibernate вернет вас прилагается объектов. Поэтому, если вы просто вызываете cachedEntity.getNonCachedEntity(), Hibernate будет ленить загрузку не кэшированного объекта точно так же, как если бы у вас не было кеша вообще.

Независимо от того, принадлежит ли сущность из базы данных или из кеша второго уровня, ничего не меняет: если атрибут ленивый, и если этот атрибут открывается после закрытия сеанса, тогда ленивый атрибут должен быть инициализируется до закрытия сессии.

Звоните Hibernate.initialize(foo.getInventotyItem()), чтобы его инициализировать.

Дополнительная информация в Hibernate documentation.

+0

", и если этот атрибут доступен после закрытия сеанса, тогда ленивый атрибут должен быть инициализирован до закрытия сеанса". Как я узнаю, что при первом извлечении этого объекта будет использоваться вне сеанса ?! Ваше предложение похоже на инициализацию кэшированного кэшируемого объекта каждый раз, что наверняка полностью разрушает преимущество использования ленивых атрибутов. –

+0

Вам не нужно инициализировать ленивые атрибуты во время поиска. Вы должны только убедиться, что он инициализирован до закрытия сеанса, если вы собираетесь получить к нему доступ после этого.Простейшие способы не иметь этой проблемы - либо не получить доступ к любому атрибуту после закрытия сеанса (т. Е. Закрыть его только тогда, когда вы закончите использовать сущность, используя открытый скрипт для просмотра), или избегать использования объектов после закрытия сеанса (например, путем преобразования объектов в DTO) –

+0

Итак, вот тест. Я вызываю метод репозитория в первый раз, и его результат с ленивыми неинициализированными реквизитами кэшируется. Тема закончилась. Из другого потока я вызываю тот же метод и получаю Lazy Exception при попытке прочитать эти реквизиты. Почему, черт возьми, мне нужно сделать какую-то дополнительную работу (т. Е. Явно открыть сеанс) вместо делегирования этого программного обеспечения для кеширования? Может быть, есть еще одно решение с конфигурацией кеша? –

 Смежные вопросы

  • Нет связанных вопросов^_^