[hibernate-commits] Hibernate SVN: r18954 - in core/trunk/core/src/main/java/org/hibernate: persister/entity and 1 other directory.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Wed Mar 10 05:25:04 EST 2010


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(



More information about the hibernate-commits mailing list