Author: steve.ebersole(a)jboss.com
Date: 2006-11-07 19:01:34 -0500 (Tue, 07 Nov 2006)
New Revision: 10760
Added:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/AbstractOperationTestCase.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/DeleteTest.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OpsSuite.java
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultDeleteEventListener.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/CreateTest.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/MergeTest.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/Node.hbm.xml
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/Node.java
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml
Log:
hhh-1564 : delete + versioned + collections = extra updates
Modified:
branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultDeleteEventListener.java
===================================================================
---
branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultDeleteEventListener.java 2006-11-08
00:00:53 UTC (rev 10759)
+++
branches/Branch_3_2/Hibernate3/src/org/hibernate/event/def/DefaultDeleteEventListener.java 2006-11-08
00:01:34 UTC (rev 10760)
@@ -147,8 +147,10 @@
*
* @param session The session which is the source of the event
* @param entity The entity being delete processed
- * @param cascadeDeleteEnabled
+ * @param cascadeDeleteEnabled Is cascading of deletes enabled
* @param persister The entity persister
+ * @param transientEntities A cache of already visited transient entities
+ * (to avoid infinite recursion).
*/
protected void deleteTransientEntity(
EventSource session,
@@ -182,9 +184,7 @@
}
final PersistenceContext persistenceContext = session.getPersistenceContext();
-
- Type[] propTypes = persister.getPropertyTypes();
-
+ final Type[] propTypes = persister.getPropertyTypes();
final Object version = entityEntry.getVersion();
final Object[] currentState;
@@ -195,14 +195,7 @@
currentState = entityEntry.getLoadedState();
}
- final Object[] deletedState = new Object[propTypes.length];
- TypeFactory.deepCopy(
- currentState,
- propTypes,
- persister.getPropertyUpdateability(),
- deletedState,
- session
- );
+ final Object[] deletedState = createDeletedState( persister, currentState, session );
entityEntry.setDeletedState(deletedState);
session.getInterceptor().onDelete(
@@ -211,7 +204,7 @@
deletedState,
persister.getPropertyNames(),
propTypes
- );
+ );
// before any callbacks, etc, so subdeletions see that this deletion happened first
persistenceContext.setEntryStatus(entityEntry, Status.DELETED);
@@ -220,7 +213,7 @@
cascadeBeforeDelete( session, persister, entity, entityEntry, transientEntities );
new ForeignKeys.Nullifier(entity, true, false, session)
- .nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
+ .nullifyTransientReferences( entityEntry.getDeletedState(), propTypes );
new Nullability(session).checkNullability( entityEntry.getDeletedState(), persister,
true );
persistenceContext.getNullifiableEntityKeys().add(key);
@@ -234,8 +227,8 @@
persister,
isCascadeDeleteEnabled,
session
- )
- );
+ )
+ );
cascadeAfterDelete( session, persister, entity, transientEntities );
@@ -243,7 +236,16 @@
// override the stale snapshot
// This is now handled by removeEntity() in EntityDeleteAction
//persistenceContext.removeDatabaseSnapshot(key);
+ }
+ private Object[] createDeletedState(EntityPersister persister, Object[] currentState,
EventSource session) {
+ Type[] propTypes = persister.getPropertyTypes();
+ final Object[] deletedState = new Object[propTypes.length];
+// TypeFactory.deepCopy( currentState, propTypes, persister.getPropertyUpdateability(),
deletedState, session );
+ boolean[] copyability = new boolean[propTypes.length];
+ java.util.Arrays.fill( copyability, true );
+ TypeFactory.deepCopy( currentState, propTypes, copyability, deletedState, session );
+ return deletedState;
}
protected boolean invokeDeleteLifecycle(EventSource session, Object entity,
EntityPersister persister) {
Added:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/AbstractOperationTestCase.java
===================================================================
---
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/AbstractOperationTestCase.java 2006-11-08
00:00:53 UTC (rev 10759)
+++
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/AbstractOperationTestCase.java 2006-11-08
00:01:34 UTC (rev 10760)
@@ -0,0 +1,51 @@
+package org.hibernate.test.ops;
+
+import java.util.Iterator;
+
+import org.hibernate.test.TestCase;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.cfg.Environment;
+import org.hibernate.Session;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public abstract class AbstractOperationTestCase extends TestCase {
+ public AbstractOperationTestCase(String name) {
+ super( name );
+ }
+
+ protected void configure(Configuration cfg) {
+ cfg.setProperty( Environment.GENERATE_STATISTICS, "true");
+ cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" );
+ }
+
+ protected String[] getMappings() {
+ return new String[] { "ops/Node.hbm.xml", "ops/Employer.hbm.xml",
"ops/OptLockEntity.hbm.xml" };
+ }
+
+ public String getCacheConcurrencyStrategy() {
+ return null;
+ }
+
+ protected void clearCounts() {
+ getSessions().getStatistics().clear();
+ }
+
+ protected void assertInsertCount(int expected) {
+ int inserts = ( int ) getSessions().getStatistics().getEntityInsertCount();
+ assertEquals( "unexpected insert count", expected, inserts );
+ }
+
+ protected void assertUpdateCount(int expected) {
+ int updates = ( int ) getSessions().getStatistics().getEntityUpdateCount();
+ assertEquals( "unexpected update counts", expected, updates );
+ }
+
+ protected void assertDeleteCount(int expected) {
+ int deletes = ( int ) getSessions().getStatistics().getEntityDeleteCount();
+ assertEquals( "unexpected delete counts", expected, deletes );
+ }
+}
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/CreateTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/CreateTest.java 2006-11-08
00:00:53 UTC (rev 10759)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/CreateTest.java 2006-11-08
00:01:34 UTC (rev 10760)
@@ -10,20 +10,48 @@
import org.hibernate.PersistentObjectException;
import org.hibernate.Session;
import org.hibernate.Transaction;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
import org.hibernate.exception.ConstraintViolationException;
-import org.hibernate.test.TestCase;
/**
* @author Gavin King
*/
-public class CreateTest extends TestCase {
+public class CreateTest extends AbstractOperationTestCase {
public CreateTest(String str) {
- super(str);
+ super( str );
}
-
+
+ public static Test suite() {
+ return new TestSuite( CreateTest.class );
+ }
+
+ public void testNoUpdatesOnCreateVersionedWithCollection() {
+ clearCounts();
+
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ VersionedEntity root = new VersionedEntity( "root", "root" );
+ VersionedEntity child = new VersionedEntity( "c1", "child-1" );
+ root.getChildren().add( child );
+ child.setParent( root );
+ s.save(root);
+ tx.commit();
+ s.close();
+
+ assertInsertCount( 2 );
+ assertUpdateCount( 0 );
+ assertDeleteCount( 0 );
+
+ s = openSession();
+ tx = s.beginTransaction();
+ s.delete( root );
+ tx.commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
public void testCreateTree() {
clearCounts();
@@ -186,40 +214,5 @@
tx.commit();
s.close();
}
-
- private void clearCounts() {
- getSessions().getStatistics().clear();
- }
-
- private void assertInsertCount(int count) {
- int inserts = (int) getSessions().getStatistics().getEntityInsertCount();
- assertEquals(count, inserts);
- }
-
- private void assertUpdateCount(int count) {
- int updates = (int) getSessions().getStatistics().getEntityUpdateCount();
- assertEquals(count, updates);
- }
-
- protected void configure(Configuration cfg) {
- cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
- cfg.setProperty(Environment.STATEMENT_BATCH_SIZE, "0");
- }
-
- protected String[] getMappings() {
- return new String[] {
- "ops/Node.hbm.xml",
- "ops/Employer.hbm.xml"
- };
- }
-
- public static Test suite() {
- return new TestSuite(CreateTest.class);
- }
-
- public String getCacheConcurrencyStrategy() {
- return null;
- }
-
}
Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/DeleteTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/DeleteTest.java 2006-11-08
00:00:53 UTC (rev 10759)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/DeleteTest.java 2006-11-08
00:01:34 UTC (rev 10760)
@@ -0,0 +1,91 @@
+package org.hibernate.test.ops;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+import org.hibernate.Session;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class DeleteTest extends AbstractOperationTestCase {
+ public DeleteTest(String name) {
+ super( name );
+ }
+
+ public static Test suite() {
+ return new TestSuite( DeleteTest.class );
+ }
+
+ public void testDeleteVersionedWithCollectionNoUpdate() {
+ // test adapted from HHH-1564...
+ Session s = openSession();
+ s.beginTransaction();
+ VersionedEntity c = new VersionedEntity( "c1", "child-1" );
+ VersionedEntity p = new VersionedEntity( "root", "root");
+ p.getChildren().add( c );
+ c.setParent( p );
+ s.save( p );
+ s.getTransaction().commit();
+ s.close();
+
+ clearCounts();
+
+ s = openSession();
+ s.beginTransaction();
+ VersionedEntity loadedParent = ( VersionedEntity ) s.get( VersionedEntity.class,
"root" );
+ s.delete( loadedParent );
+ s.getTransaction().commit();
+ s.close();
+
+ assertInsertCount( 0 );
+ assertUpdateCount( 0 );
+ assertDeleteCount( 2 );
+ }
+
+ public void testNoUpdateOnDelete() {
+ Session s = openSession();
+ s.beginTransaction();
+ Node node = new Node( "test" );
+ s.persist( node );
+ s.getTransaction().commit();
+ s.close();
+
+ clearCounts();
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( node );
+ s.getTransaction().commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+ }
+
+ public void testNoUpdateOnDeleteWithCollection() {
+ Session s = openSession();
+ s.beginTransaction();
+ Node parent = new Node( "parent" );
+ Node child = new Node( "child" );
+ parent.getCascadingChildren().add( child );
+ s.persist( parent );
+ s.getTransaction().commit();
+ s.close();
+
+ clearCounts();
+
+ s = openSession();
+ s.beginTransaction();
+ parent = ( Node ) s.get( Node.class, "parent" );
+ s.delete( parent );
+ s.getTransaction().commit();
+ s.close();
+
+ assertUpdateCount( 0 );
+ assertInsertCount( 0 );
+ assertDeleteCount( 2 );
+ }
+}
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/MergeTest.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-11-08
00:00:53 UTC (rev 10759)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/MergeTest.java 2006-11-08
00:01:34 UTC (rev 10760)
@@ -11,20 +11,21 @@
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.NonUniqueObjectException;
-import org.hibernate.cfg.Configuration;
-import org.hibernate.cfg.Environment;
import org.hibernate.criterion.Projections;
-import org.hibernate.test.TestCase;
/**
* @author Gavin King
*/
-public class MergeTest extends TestCase {
+public class MergeTest extends AbstractOperationTestCase {
public MergeTest(String str) {
- super(str);
+ super( str );
}
+ public static Test suite() {
+ return new TestSuite( MergeTest.class );
+ }
+
public void testNoExtraUpdatesOnMerge() throws Exception {
Session s = openSession();
s.beginTransaction();
@@ -505,34 +506,7 @@
cleanup();
}
-
- private void clearCounts() {
- getSessions().getStatistics().clear();
- }
-
- private void assertInsertCount(int expected) {
- int inserts = (int) getSessions().getStatistics().getEntityInsertCount();
- assertEquals( "unexpected insert count", expected, inserts );
- }
-
- private void assertUpdateCount(int expected) {
- int updates = (int) getSessions().getStatistics().getEntityUpdateCount();
- assertEquals( "unexpected update counts", expected, updates );
- }
-
- protected void configure(Configuration cfg) {
- cfg.setProperty(Environment.GENERATE_STATISTICS, "true");
- cfg.setProperty(Environment.STATEMENT_BATCH_SIZE, "0");
- }
-
- protected String[] getMappings() {
- return new String[] { "ops/Node.hbm.xml", "ops/Employer.hbm.xml",
"ops/OptLockEntity.hbm.xml" };
- }
- public static Test suite() {
- return new TestSuite(MergeTest.class);
- }
-
private void cleanup() {
Session s = openSession();
s.beginTransaction();
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/Node.hbm.xml
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/Node.hbm.xml 2006-11-08
00:00:53 UTC (rev 10759)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/Node.hbm.xml 2006-11-08
00:01:34 UTC (rev 10760)
@@ -22,8 +22,11 @@
<key column="parent"/>
<one-to-many class="Node"/>
</set>
-
- </class>
+ <set name="cascadingChildren" inverse="false"
cascade="persist,merge,save-update,evict,delete">
+ <key column="CASC_PARENT"/>
+ <one-to-many class="Node"/>
+ </set>
+ </class>
<class name="NumberedNode" polymorphism="explicit">
<id name="id" unsaved-value="0">
Modified: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/Node.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/Node.java 2006-11-08
00:00:53 UTC (rev 10759)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/Node.java 2006-11-08
00:01:34 UTC (rev 10760)
@@ -9,47 +9,34 @@
* @author Gavin King
*/
public class Node {
-
+
private String name;
+ private String description;
+ private Date created;
private Node parent;
private Set children = new HashSet();
- private String description;
- private Date created;
-
- public Node() {}
-
+ private Set cascadingChildren = new HashSet();
+
+ public Node() {
+ }
+
public Node(String name) {
this.name = name;
created = generateCurrentDate();
}
- public Set getChildren() {
- return children;
- }
- public void setChildren(Set children) {
- this.children = children;
- }
public String getName() {
return name;
}
+
public void setName(String name) {
this.name = name;
}
- public Node getParent() {
- return parent;
- }
- public void setParent(Node parent) {
- this.parent = parent;
- }
-
- public Node addChild(Node child) {
- children.add(child);
- child.setParent(this);
- return this;
- }
+
public String getDescription() {
return description;
}
+
public void setDescription(String description) {
this.description = description;
}
@@ -62,6 +49,36 @@
this.created = created;
}
+ public Node getParent() {
+ return parent;
+ }
+
+ public void setParent(Node parent) {
+ this.parent = parent;
+ }
+
+ public Set getChildren() {
+ return children;
+ }
+
+ public void setChildren(Set children) {
+ this.children = children;
+ }
+
+ public Node addChild(Node child) {
+ children.add( child );
+ child.setParent( this );
+ return this;
+ }
+
+ public Set getCascadingChildren() {
+ return cascadingChildren;
+ }
+
+ public void setCascadingChildren(Set cascadingChildren) {
+ this.cascadingChildren = cascadingChildren;
+ }
+
private Date generateCurrentDate() {
// Note : done as java.sql.Date mainly to work around issue with
// MySQL and its lack of milli-second precision on its DATETIME
Added: branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OpsSuite.java
===================================================================
--- branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OpsSuite.java 2006-11-08
00:00:53 UTC (rev 10759)
+++ branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OpsSuite.java 2006-11-08
00:01:34 UTC (rev 10760)
@@ -0,0 +1,21 @@
+package org.hibernate.test.ops;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * {@inheritDoc}
+ *
+ * @author Steve Ebersole
+ */
+public class OpsSuite {
+ public static Test suite() {
+ TestSuite suite = new TestSuite( "Operations tests" );
+ suite.addTest( CreateTest.suite() );
+ suite.addTest( DeleteTest.suite() );
+ suite.addTest( GetLoadTest.suite() );
+ suite.addTest( MergeTest.suite() );
+ suite.addTest( SaveOrUpdateTest.suite() );
+ return suite;
+ }
+}
Modified:
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml
===================================================================
---
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml 2006-11-08
00:00:53 UTC (rev 10759)
+++
branches/Branch_3_2/Hibernate3/test/org/hibernate/test/ops/OptLockEntity.hbm.xml 2006-11-08
00:01:34 UTC (rev 10760)
@@ -18,7 +18,7 @@
<many-to-one name="parent" class="VersionedEntity"/>
<set name="children"
inverse="true"
- cascade="persist,merge,save-update,evict">
+ cascade="persist,merge,save-update,evict,delete">
<key column="parent"/>
<one-to-many class="VersionedEntity"/>
</set>