public static class RootAwareInsertEventListener RootAwareUpdateAndDeleteEventListener implements PersistEventListenerFlushEntityEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(RootAwareInsertEventListenerRootAwareUpdateAndDeleteEventListener.class); public static final RootAwareInsertEventListenerRootAwareUpdateAndDeleteEventListener INSTANCE = new RootAwareInsertEventListenerRootAwareUpdateAndDeleteEventListener(); @Override public void onPersistonFlushEntity(PersistEventFlushEntityEvent event) throws HibernateException { final EntityEntry entry = event.getEntityEntry(); final Object entity = event.getObjectgetEntity(); final boolean mightBeDirty = entry.requiresDirtyCheck( entity ); if(mightBeDirty && entity instanceof RootAware) { RootAware rootAware = (RootAware) entity; if(updated(event)) { Object root = rootAware.root(); event LOGGER.getSessioninfo("Incrementing {} entity version because a {} child entity has been updated", root, entity).lock; incrementRootVersion(rootevent, LockMode.OPTIMISTIC_FORCE_INCREMENTroot); } else if (deleted(event)) { Object root = rootAware.root(); LOGGER.info("Incrementing {} entity version because a {} child entity has been inserted"deleted", root, entity); } incrementRootVersion(event, root); } } @Override} public private void onPersistincrementRootVersion(PersistEventFlushEntityEvent event, MapObject createdAlreadyroot) { throwsevent.getSession().lock(root, HibernateExceptionLockMode.OPTIMISTIC_FORCE_INCREMENT); } private boolean deleted(FlushEntityEvent event) { onPersistreturn 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; } }