Я использовал свой собственный объектный кеш, который работает более или менее:
- получить объект по фиксированным критериям (например, использовать по имени пользователя)
- сохранить этот объектв hashmap, как он используется снова и снова
- если в другой сессии снова запрашивается тот же объект, я снова использую тот же объект.
- Мои объекты меняются очень редко и используются крайнечасто (только для чтения).У меня есть хуки, которые очищают мой объектный кеш, если что-либо меняется в базе данных.
Теперь это работает довольно хорошо в большинстве ситуаций, но в некоторых случаях вызывает нежелательные попадания в базу данных.Я идентифицировал следующую ситуацию:
- Я создаю объект (new Car ())
- , назначаю кешированный объект этому объекту: car.setOwner (cache.lookup ("Пит ")) (этот объект был извлечен из базы данных в другом сеансе 20 минут назад)
- затем я сохраняю объект
В этот момент Hibernate понимает, что этот объект 'dettached 'и во время проверки на нулевое значение он снова получает этот объект из базы данных.
Есть ли способ избежать этого?Могу ли я присоединить объект к сеансу без попадания в базу данных?«Поверьте мне, hiberante, это действительный объект, пожалуйста, помните его».
Ниже я прикрепляю трассировку стека в этой ситуации.
Hibernate Версия: 3.3.2.GA
Cheers Reto
org.hibernate.jdbc.util.SQLStatementLogger.logStatement(SQLStatementLogger.java:115)
org.hibernate.jdbc.AbstractBatcher.log(AbstractBatcher.java:444)
org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:511)
org.hibernate.jdbc.AbstractBatcher.prepareSelectStatement(AbstractBatcher.java:145)
org.hibernate.persister.entity.AbstractEntityPersister.getDatabaseSnapshot(AbstractEntityPersister.java:1034)
org.hibernate.engine.StatefulPersistenceContext.getDatabaseSnapshot(StatefulPersistenceContext.java:269)
org.hibernate.engine.ForeignKeys.isTransient(ForeignKeys.java:212)
org.hibernate.engine.ForeignKeys$Nullifier.isNullifiable(ForeignKeys.java:160)
org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:92)
org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:70)
org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:311)
org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:144)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:563)
org.hibernate.impl.SessionImpl.save(SessionImpl.java:551)
org.hibernate.impl.SessionImpl.save(SessionImpl.java:547)
sun.reflect.GeneratedMethodAccessor271.invoke (Unknown Source)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessor