Author: gbadner
Date: 2010-03-10 05:25:03 -0500 (Wed, 10 Mar 2010)
New Revision: 18954
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
Log:
HHH-4993 : Updates to read-only entity associations made while in persistent state are
ignored by flush
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java 2010-03-10
09:59:43 UTC (rev 18953)
+++
core/trunk/core/src/main/java/org/hibernate/event/def/AbstractFlushingEventListener.java 2010-03-10
10:25:03 UTC (rev 18954)
@@ -141,7 +141,7 @@
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 );
}
}
Modified:
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2010-03-10
09:59:43 UTC (rev 18953)
+++
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultFlushEntityEventListener.java 2010-03-10
10:25:03 UTC (rev 18954)
@@ -478,7 +478,7 @@
}
private boolean isCollectionDirtyCheckNecessary(EntityPersister persister, Status
status) {
- return status==Status.MANAGED &&
+ return ( status == Status.MANAGED || status == Status.READ_ONLY ) &&
persister.isVersioned() &&
persister.hasCollections();
}
Modified:
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java
===================================================================
---
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-03-10
09:59:43 UTC (rev 18953)
+++
core/trunk/core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java 2010-03-10
10:25:03 UTC (rev 18954)
@@ -2759,14 +2759,8 @@
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 @@
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(
Show replies by date