Как регистрировать изменения @Entity с помощью @EntityListeners? - PullRequest
1 голос
/ 27 марта 2019

Я хочу создать регистратор, который регистрирует любые операции CRUD на объекте.Это просто на insert или delete.Но как я могу получить доступ к предыдущей сущности во время процесса update, чтобы я мог регистрировать измененные поля (например, доступ через отражение).

@Entity
@EntityListeners(AuditingEntityListener.class)
public class MyEntity {
}

public class AuditEntityListener {
    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
    private static final Marker AUDIT = MarkerFactory.getMarker("AUDIT");

    @PrePersist
    public void prePersist(Object target) {
        log("new object inserted", target);
    }

    @PreRemove
    public void preRemove(Object target) {
        log("entity deleted", target);
    }

    @PreUpdate
    public void preUpdate(Object target) {
        //TODO how can I access the "old" entity, so that I can log only changed fields (eg via reflection)?
    }
}

Ответы [ 2 ]

1 голос
/ 11 апреля 2019

Вы можете сохранить предыдущее состояние в методе PostLoad и проверить различия в методе предварительного обновления

// EDIT
@Entity
@EntityListeners(AuditingEntityListener.class)
public class MyEntity {
   @Transient
   private transient MyEntity savedState;

}

public class AuditEntityListener {
    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());
    private static final Marker AUDIT = MarkerFactory.getMarker("AUDIT");

@PostLoad
 private void saveState(MyEntity target){

    target.savedState = SerializationUtils.clone(target);
 }

@PrePersist
public void prePersist(MyEntity target) {
    log("new object inserted", target);
}

@PreRemove
public void preRemove(MyEntity target) {
    log("entity deleted", target);
}

@PreUpdate
public void preUpdate(MyEntity target) {
    MyEntity previousState = target.getSavedState();
}

}

0 голосов
/ 27 марта 2019

Попробуйте заглянуть в SPI событий Hibernate. Hibernate Envers реализует некоторые из предоставленных SPI. Я сейчас использую Hibernate 5.

Реализация интерфейса org.hibernate.event.spi.PostUpdateEventListener, который позволит переопределять public void onPostUpdate(PostUpdateEvent event). PostUpdateEvent позволяет получить доступ к некоторым полезным материалам, например, PostUpdateEvent#getOldState().

Как только вы это сделаете, вам нужно зарегистрировать этот слушатель для интегратора SPI. Реализация org.hibernate.integrator.spi.Integrator.

// Overriden public void integrate(Metadata metadata, SessionFactoryImplementor sessionFactory,
//                          SessionFactoryServiceRegistry serviceRegistry)
        final EventListenerRegistry eventListenerRegistry = serviceRegistry.getService(EventListenerRegistry.class);

        eventListenerRegistry.appendListeners(EventType.POST_UPDATE, YourListener.INSTANCE);

Затем зарегистрируйте этот интегратор в своем приложении, создав META-INF/services/org.hibernate.integrator.spi.Integrator. Внутри этого файла вам нужно поместить имя класса для вашего реализованного Hibernate Integrator. Пример:

com.company.my.ImplementedHibernateIntegrator

Другие версии Hibernate могут иметь другой подход, например, https://vladmihalcea.com/hibernate-event-listeners/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...