Java 当子实体发生更改时,如何更新根实体上已修改的_at列?
当子实体发生更改时,是否有方法告诉hibernate在根实体的列中更改Java 当子实体发生更改时,如何更新根实体上已修改的_at列?,java,spring,hibernate,Java,Spring,Hibernate,当子实体发生更改时,是否有方法告诉hibernate在根实体的列中更改modified\u? 我有60多个数据库表。有一个根实体。每当我更改任何表时,我都需要将该更改传播到根实体,并在列中更新modified\u。级联以另一种方式根->子级工作。我需要child->root。解决此问题的最佳方法是什么?有什么建议吗?我读过关于事件侦听器的内容,但我发现它对于我的用例来说太复杂了。我想不出更优雅、更容易实现的东西。有什么建议吗?我是在受启发的事件监听器中做的。我创建了两个侦听器,一个用于插入,另一
modified\u?
我有60多个数据库表。有一个根实体。每当我更改任何表时,我都需要将该更改传播到根实体,并在
列中更新modified\u。
级联
以另一种方式根->子级工作。我需要child->root。
解决此问题的最佳方法是什么?有什么建议吗?我读过关于事件侦听器的内容,但我发现它对于我的用例来说太复杂了。我想不出更优雅、更容易实现的东西。有什么建议吗?我是在受启发的事件监听器中做的。我创建了两个侦听器,一个用于插入,另一个用于更新/删除。它们拦截更改,每当发生更改时,我都会在根实体的
列中更新modified\u
@Component
public class RootAwareInsertEventListener implements PersistEventListener {
private static final Logger logger = LoggerFactory.getLogger(RootAwareInsertEventListener.class);
@Autowired
private EntityManagerFactory emf;
@PostConstruct
private void init() {
SessionFactoryImpl sessionFactory = emf.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.PERSIST).appendListener(this);
}
/**
* Intercept hibernate persist - and if entity is RootAware it will update modified_at of root entity
*/
@Override
public void onPersist(PersistEvent event) throws HibernateException {
final Object entity = event.getObject();
if (entity instanceof RootAware) {
RootAware rootAware = (RootAware) entity;
MortgageCase root = (MortgageCase) rootAware.root();
logger.info("Modifing {} modified_at because a {} child entity has been inserted", root, entity);
root.setModifiedAt(new Date());
}
}
@Override
public void onPersist(PersistEvent event, Map createdAlready) throws HibernateException {
onPersist(event);
}
}
@Component
public class RootAwareUpdateAndDeleteEventListener implements FlushEntityEventListener {
private static final Logger logger = LoggerFactory.getLogger(RootAwareUpdateAndDeleteEventListener.class);
@Autowired
private EntityManagerFactory emf;
@PostConstruct
private void init() {
SessionFactoryImpl sessionFactory = emf.unwrap(SessionFactoryImpl.class);
EventListenerRegistry registry = sessionFactory.getServiceRegistry().getService(EventListenerRegistry.class);
registry.getEventListenerGroup(EventType.FLUSH_ENTITY).appendListener(this);
}
/**
* Intercept hibernate update / delete - and if entity is RootAware it will update modified_at of root entity
*/
@Override
public void onFlushEntity(FlushEntityEvent event) throws HibernateException {
final EntityEntry entry = event.getEntityEntry();
final Object entity = event.getEntity();
final boolean mightBeDirty = entry.requiresDirtyCheck(entity);
if (mightBeDirty && entity instanceof RootAware) {
RootAware rootAware = (RootAware) entity;
if (updated(event)) {
MortgageCase root = (MortgageCase) rootAware.root();
logger.info("Modifing {} modified_at because a {} child entity has been updated", root, entity);
root.setModifiedAt(new Date());
} else if (deleted(event)) {
MortgageCase root = (MortgageCase) rootAware.root();
logger.info("Modifing {} modified_at because a {} child entity has been deleted", root, entity);
root.setModifiedAt(new Date());
}
}
}
private boolean deleted(FlushEntityEvent event) {
return event.getEntityEntry().getStatus() == Status.DELETED;
}
private boolean updated(FlushEntityEvent event) {
final EntityEntry entry = event.getEntityEntry();
final Object entity = event.getEntity();
int[] dirtyProperties;
EntityPersister persister = entry.getPersister();
final Object[] values = event.getPropertyValues();
SessionImplementor session = event.getSession();
if (event.hasDatabaseSnapshot()) {
dirtyProperties = persister.findModified(event.getDatabaseSnapshot(), values, entity, session);
} else {
dirtyProperties = persister.findDirty(values, entry.getLoadedState(), entity, session);
}
return dirtyProperties != null;
}
}