Hibernate version: 3.2.5
Name and version of the database you are using: Oracle 10g
Question regarding the cascade behavior during the flushEverythingToExecution. I've got a listener set up for saveOrUpdate events and noticed that it is firing way more than I would have expected.
It looks like during the cascading of the associations it will always fire a saveUdate event even if nothing on the entity has changed. i.e. in my case I am doing a bunch of fetches but then during the commit of the transaction a load of saveUpdate events are fired. Is this normal?
It looks like the AbstractFlushingEventListener is going to fire a cascade which on anything that is in a MANAGED state which will in turn trigger a saveUpdate. MANAGED is the default for anything loaded during the session I believe.
Code:
private void prepareEntityFlushes(EventSource session) throws HibernateException {
log.debug("processing flush-time cascades");
final Map.Entry[] list = IdentityMap.concurrentEntries( session.getPersistenceContext().getEntityEntries() );
//safe from concurrent modification because of how entryList() is implemented on IdentityMap
final int size = list.length;
final Object anything = getAnything();
for ( int i=0; i<size; i++ ) {
Map.Entry me = list[i];
EntityEntry entry = (EntityEntry) me.getValue();
Status status = entry.getStatus();
if ( status == Status.MANAGED || status == Status.SAVING ) {
cascadeOnFlush( session, entry.getPersister(), me.getKey(), anything );
}
}
}
The cascade on flush gets called:
Code:
private void cascadeOnFlush(EventSource session, EntityPersister persister, Object object, Object anything)
throws HibernateException {
session.getPersistenceContext().incrementCascadeLevel();
try {
new Cascade( getCascadingAction(), Cascade.BEFORE_FLUSH, session )
.cascade( persister, object, anything );
}
finally {
session.getPersistenceContext().decrementCascadeLevel();
}
}
The cascading action is a SAVE_UPDATE action which does the following:
Code:
public void cascade(EventSource session, Object child, String entityName, Object anything, boolean isCascadeDeleteEnabled)
throws HibernateException {
if ( log.isTraceEnabled() ) {
log.trace( "cascading to saveOrUpdate: " + entityName );
}
session.saveOrUpdate(entityName, child);
}
Which then ends up triggering all of the saveUpdate listeners.
Is this required? It would seem to me that it should check the dirtyness of an entity before calling update on it but am I missing something? It just seems strange to me that it would process all of the saveUpdates on a session that contains unmodified entities.