HHH-4993 : Updates to read-only entity associations made while in persistent state are ignored by flush

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18954 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Gail Badner 2010-03-10 10:25:03 +00:00
parent 268e778d5c
commit 9f1444eb15
3 changed files with 24 additions and 10 deletions

View File

@ -141,7 +141,7 @@ public abstract class AbstractFlushingEventListener implements Serializable {
Map.Entry me = list[i];
EntityEntry entry = (EntityEntry) me.getValue();
Status status = entry.getStatus();
if ( status == Status.MANAGED || status == Status.SAVING ) {
if ( status == Status.MANAGED || status == Status.SAVING || status == Status.READ_ONLY ) {
cascadeOnFlush( session, entry.getPersister(), me.getKey(), anything );
}
}

View File

@ -478,7 +478,7 @@ public class DefaultFlushEntityEventListener implements FlushEntityEventListener
}
private boolean isCollectionDirtyCheckNecessary(EntityPersister persister, Status status) {
return status==Status.MANAGED &&
return ( status == Status.MANAGED || status == Status.READ_ONLY ) &&
persister.isVersioned() &&
persister.hasCollections();
}

View File

@ -2759,14 +2759,8 @@ public abstract class AbstractEntityPersister
if ( entry == null && ! isMutable() ) {
throw new IllegalStateException( "Updating immutable entity that is not in session yet!" );
}
if ( entry != null && ! isModifiableEntity( entry ) && entry.getStatus() != Status.DELETED ) {
throw new IllegalStateException( "Updating non-modifiable entity that is not being deleted!" );
}
if ( ( entityMetamodel.isDynamicUpdate() || ! isModifiableEntity( entry ) ) && dirtyFields != null ) {
// For the following cases we need to generate the UPDATE SQL
// - dynamic-update="true"
// - a non-modifiable entity (e.g., read-only or immutable) needs to have
// references to transient entities set to null before being deleted
if ( ( entityMetamodel.isDynamicUpdate() && dirtyFields != null ) ) {
// We need to generate the UPDATE SQL when dynamic-update="true"
propsToUpdate = getPropertiesToUpdate( dirtyFields, hasDirtyCollection );
// don't need to check laziness (dirty checking algorithm handles that)
updateStrings = new String[span];
@ -2776,6 +2770,26 @@ public abstract class AbstractEntityPersister
null;
}
}
else if ( ! isModifiableEntity( entry ) ) {
// We need to generate UPDATE SQL when a non-modifiable entity (e.g., read-only or immutable)
// needs:
// - to have references to transient entities set to null before being deleted
// - to have version incremented do to a "dirty" association
// If dirtyFields == null, then that means that there are no dirty properties to
// to be updated; an empty array for the dirty fields needs to be passed to
// getPropertiesToUpdate() instead of null.
propsToUpdate = getPropertiesToUpdate(
( dirtyFields == null ? ArrayHelper.EMPTY_INT_ARRAY : dirtyFields ),
hasDirtyCollection
);
// don't need to check laziness (dirty checking algorithm handles that)
updateStrings = new String[span];
for ( int j = 0; j < span; j++ ) {
updateStrings[j] = tableUpdateNeeded[j] ?
generateUpdateString( propsToUpdate, j, oldFields, j == 0 && rowId != null ) :
null;
}
}
else {
// For the case of dynamic-update="false", or no snapshot, we use the static SQL
updateStrings = getUpdateStrings(