Skip to main content
deleted 98 characters in body
Source Link
Vlad Mihalcea
  • 155.9k
  • 85
  • 599
  • 984

You can propagate changes from child entities to parent entities. This requires you to propagate the OPTIMISTIC_FORCE_INCREMENTOPTIMISTIC_FORCE_INCREMENT lock whenever the child entity is modified.

This article explains in great details the way you should be implementing such a use case.

In shortSo, you need to have all your entities implementing a RootAwareRootAware interface:

You can propagate changes from child entities to parent entities. This requires you to propagate the OPTIMISTIC_FORCE_INCREMENT lock whenever the child entity is modified.

This article explains in great details the way you should be implementing such a use case.

In short, you need to have all your entities implementing a RootAware interface:

You can propagate changes from child entities to parent entities. This requires you to propagate the OPTIMISTIC_FORCE_INCREMENT lock whenever the child entity is modified.

So, you need to have all your entities implementing a RootAware interface:

added 1604 characters in body
Source Link
Vlad Mihalcea
  • 155.9k
  • 85
  • 599
  • 984
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; } } 
public static class RootAwareInsertEventListener implements PersistEventListener { private static final Logger LOGGER =  LoggerFactory.getLogger(RootAwareInsertEventListener.class); public static final RootAwareInsertEventListener INSTANCE =  new RootAwareInsertEventListener(); @Override public void onPersist(PersistEvent event) throws HibernateException { final Object entity = event.getObject(); if(entity instanceof RootAware) { RootAware rootAware = (RootAware) entity; Object root = rootAware.root(); event.getSession().lock(root, LockMode.OPTIMISTIC_FORCE_INCREMENT); LOGGER.info("Incrementing {} entity version because a {} child entity has been inserted", root, entity); } } @Override public void onPersist(PersistEvent event, Map createdAlready) throws HibernateException { onPersist(event); } } 
public class RootAwareUpdateAndDeleteEventListener implements FlushEntityEventListener { private static final Logger LOGGER = LoggerFactory.getLogger(RootAwareUpdateAndDeleteEventListener.class); public static final RootAwareUpdateAndDeleteEventListener INSTANCE = new RootAwareUpdateAndDeleteEventListener(); @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)) {  Object root = rootAware.root();  LOGGER.info("Incrementing {} entity version because a {} child entity has been updated", root, entity); incrementRootVersion(event, root);   }   else if (deleted(event)) { Object root = rootAware.root(); LOGGER.info("Incrementing {} entity version because a {} child entity has been deleted",  root, entity);  incrementRootVersion(event, root);   }   } }     private void incrementRootVersion(FlushEntityEvent event, Object root) { event.getSession().lock(root, LockMode.OPTIMISTIC_FORCE_INCREMENT);  } 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; } } 
deleted 22 characters in body
Source Link
Vlad Mihalcea
  • 155.9k
  • 85
  • 599
  • 984

You can propagate changes from child entities to parent entities. This requires you to propagate the OPTIMISTIC_FORCE_INCREMENTOPTIMISTIC_FORCE_INCREMENT lock whenever the child entity is modified.

This articleThis article explains in great details the way you should be implementing such a use case.

You can propagate changes from child entities to parent entities. This requires you to propagate the OPTIMISTIC_FORCE_INCREMENT lock whenever the child entity is modified.

This article explains in great details the way you should be implementing such a use case.

You can propagate changes from child entities to parent entities. This requires you to propagate the OPTIMISTIC_FORCE_INCREMENT lock whenever the child entity is modified.

This article explains in great details the way you should be implementing such a use case.

added 1398 characters in body
Source Link
Vlad Mihalcea
  • 155.9k
  • 85
  • 599
  • 984
Loading
Source Link
Vlad Mihalcea
  • 155.9k
  • 85
  • 599
  • 984
Loading