Спящий режим DefaultSaveOrUpdateEventListener, проверяющий события вставки и обновления базы данных

#hibernate #spring #event-listener

#переход в спящий режим #spring #прослушиватель событий

Вопрос:

Использование hibernate 3.3.2.ga и Spring 3.0.5.RELEASE.

Реализовали что-то, как описано здесь..

с другой конфигурацией, поскольку я использую Spring managed SessionFactory

 <bean id="sessionFactoryPGAD" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource" ref="dataSourcePGAD"/>
.......
.......
<property name="eventListeners">
    <map>
        <entry key="save-update"><ref local="auditEntityListener" /></entry>
    </map>
</property>
  

чтобы добавить аудит при вызове моего DAOs

 ...getCurrentSession().saveOrUpdate(...
  

Однако в моем расширенном DefaultSaveOrUpdateEventListener (компонент с именем auditEntityListener) Мне было интересно, есть ли какой-либо способ определить, является ли объект, сохраняемый в БД, новой записью или обновлением существующей?

Я пытался посмотреть на

 EntityEntry entityEntry = event.getEntry();
if (entityEntry.isExistsInDatabase())
{.....
  

но EntityEntry имеет значение null для объекта, который, как я знаю, существует в БД.

Другие методы SaveOrUpdateEvent, такие как getRequestedId() и getResultId(), также возвращают null.

Как я мог бы определить, будет ли вызов hibernate вставкой или обновлением из DefaultSaveOrUpdateEventListener?

Ответ №1:

Метод, который вы ищете, — это getEntityState(). Вот пример его использования, взятый из исходного кода DefaultSaveOrUpdateEventListener:

 int entityState = getEntityState(
    event.getEntity(),
    event.getEntityName(),
    event.getEntry(),
    event.getSession()
);

switch ( entityState ) {
    case DETACHED:
        entityIsDetached( event );
        return null;
    case PERSISTENT:
        return entityIsPersistent( event );
    default: //TRANSIENT or DELETED
        return entityIsTransient( event );
}
  

Если вам нужно сделать что-то другое для сохранения по сравнению с обновлением, вы можете рассмотреть возможность использования отдельных EventListeners, одного, который расширяет DefaultSaveEventListener, и другого, который расширяет DefaultUpdateEventListener, и разрешить Hibernate отправлять правильному прослушивателю для вас.

Комментарии:

1. спасибо за это — изначально у меня было 2 прослушивателя, которые прослушивали события предварительной вставки и предварительного обновления (используя предоставленные интерфейсы), но прослушиватели событий не получали никаких событий, поскольку при вызовах моего DAO запускалось только событие сохранения обновления .getCurrentSession().saveOrUpdate (… как мне заставить hibernate отправлять правильному прослушивателю, если единственным событием является событие сохранения обновления …?

2. Также вызов getEntityState(event.getEntity(), event.getEntityName(), event.getEntry(), event.getSession()) не работает, поскольку event.getEntry() выдает NPE, как это было при проверке if (EntityEntry.isExistsInDatabase()), как упоминалось выше………

3. Не просматривая весь ваш код для контекста, похоже, что ваш объект может быть отсоединен во время вызова saveOrUpdate. Ознакомьтесь с исходным кодом getEntityState(), чтобы увидеть, как это работает: docjar.com/html/api/org/hibernate/event/def /…