diff --git a/core/src/main/java/org/hibernate/type/ManyToOneType.java b/core/src/main/java/org/hibernate/type/ManyToOneType.java
index 04c320277d..09de57dd53 100644
--- a/core/src/main/java/org/hibernate/type/ManyToOneType.java
+++ b/core/src/main/java/org/hibernate/type/ManyToOneType.java
@@ -88,10 +88,11 @@ public class ManyToOneType extends EntityType {
}
public boolean isAlwaysDirtyChecked() {
- // If we have not-found="ignore" association mapped to a
- // formula, we always need to dirty check it, so we can update the
- // second-level cache
- return ignoreNotFound;
+ // always need to dirty-check, even when non-updateable;
+ // this ensures that when the association is updated,
+ // the entity containing this association will be updated
+ // in the cache
+ return true;
}
public boolean isOneToOne() {
diff --git a/testsuite/src/test/java/org/hibernate/test/onetomany/AbstractRecursiveBidirectionalOneToManyTest.java b/testsuite/src/test/java/org/hibernate/test/onetomany/AbstractRecursiveBidirectionalOneToManyTest.java
index 807dba93ab..4aac6e529c 100644
--- a/testsuite/src/test/java/org/hibernate/test/onetomany/AbstractRecursiveBidirectionalOneToManyTest.java
+++ b/testsuite/src/test/java/org/hibernate/test/onetomany/AbstractRecursiveBidirectionalOneToManyTest.java
@@ -27,6 +27,7 @@ package org.hibernate.test.onetomany;
import java.util.ArrayList;
import org.hibernate.CacheMode;
+import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.junit.functional.FunctionalTestCase;
@@ -65,36 +66,43 @@ public abstract class AbstractRecursiveBidirectionalOneToManyTest extends Functi
return new String[] { "onetomany/Node.hbm.xml" };
}
- public void testOneToManyMoveElement() {
- init();
- transformMove();
- check();
+ public void testOneToManyMoveElement() {
+ init();
+ transformMove();
+ check( false );
delete();
- }
+ }
+
+ public void testOneToManyMoveElementWithDirtySimpleProperty() {
+ init();
+ transformMoveWithDirtySimpleProperty();
+ check( true );
+ delete();
+ }
public void testOneToManyReplaceList() {
init();
transformReplace();
- check();
+ check( false );
delete();
}
- void init() {
+ void init() {
Session s = openSession();
Transaction tx = s.beginTransaction();
- Node node1 = new Node( 1 );
- Node node2 = new Node( 2 );
- Node node3 = new Node( 3 );
+ Node node1 = new Node( 1, "node1" );
+ Node node2 = new Node( 2, "node2" );
+ Node node3 = new Node( 3, "node3" );
- node1.addSubNode( node2 );
- node2.addSubNode( node3 );
+ node1.addSubNode( node2 );
+ node2.addSubNode( node3 );
- s.save(node1);
+ s.save(node1);
tx.commit();
- s.close();
+ s.close();
}
void transformMove() {
@@ -113,6 +121,23 @@ public abstract class AbstractRecursiveBidirectionalOneToManyTest extends Functi
s.close();
}
+ void transformMoveWithDirtySimpleProperty() {
+
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+
+ Node node3 = (Node) s.load(Node.class, new Integer(3));
+ Node node2 = node3.getParentNode();
+ Node node1 = node2.getParentNode();
+
+ node2.removeSubNode( node3 );
+ node1.addSubNode( node3 );
+ node3.setDescription( "node3-updated" );
+
+ tx.commit();
+ s.close();
+ }
+
void transformReplace() {
Session s = openSession();
@@ -131,21 +156,32 @@ public abstract class AbstractRecursiveBidirectionalOneToManyTest extends Functi
s.close();
}
- void check() {
-
+ void check(boolean simplePropertyUpdated) {
Session s = openSession();
Transaction tx = s.beginTransaction();
- Node node3 = (Node) s.get(Node.class, new Integer(3));
+ Node node3 = (Node) s.get( Node.class, new Integer(3) );
// fails with 2nd level cache enabled
- assertEquals(1, node3.getParentNode().getId().intValue());
+ assertEquals( 1, node3.getParentNode().getId().intValue() );
+ assertEquals( ( simplePropertyUpdated ? "node3-updated" : "node3" ), node3.getDescription() );
+ assertTrue( node3.getSubNodes().isEmpty() );
+
+ Node node1 = node3.getParentNode();
+ assertNull( node1.getParentNode() );
+ assertEquals( 2, node1.getSubNodes().size() );
+ assertEquals( 2, ( ( Node ) node1.getSubNodes().get( 0 ) ).getId().intValue() );
+ assertEquals( "node1", node1.getDescription() );
+
+ Node node2 = ( Node ) node1.getSubNodes().get( 0 );
+ assertSame( node1, node2.getParentNode() );
+ assertTrue( node2.getSubNodes().isEmpty() );
+ assertEquals( "node2", node2.getDescription() );
tx.commit();
s.close();
}
void delete() {
-
Session s = openSession();
Transaction tx = s.beginTransaction();
Node node1 = ( Node ) s.get( Node.class, new Integer( 1 ) );
@@ -153,4 +189,4 @@ public abstract class AbstractRecursiveBidirectionalOneToManyTest extends Functi
tx.commit();
s.close();
}
-}
\ No newline at end of file
+}
diff --git a/testsuite/src/test/java/org/hibernate/test/onetomany/AbstractVersionedRecursiveBidirectionalOneToManyTest.java b/testsuite/src/test/java/org/hibernate/test/onetomany/AbstractVersionedRecursiveBidirectionalOneToManyTest.java
new file mode 100644
index 0000000000..ac88570137
--- /dev/null
+++ b/testsuite/src/test/java/org/hibernate/test/onetomany/AbstractVersionedRecursiveBidirectionalOneToManyTest.java
@@ -0,0 +1,75 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.onetomany;
+
+import java.util.ArrayList;
+
+import org.hibernate.CacheMode;
+import org.hibernate.Hibernate;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.testing.junit.functional.FunctionalTestCase;
+import org.hibernate.test.readonly.VersionedNode;
+
+/**
+ * @author Burkhard Graves, Gail Badner
+ */
+
+public abstract class AbstractVersionedRecursiveBidirectionalOneToManyTest extends AbstractRecursiveBidirectionalOneToManyTest {
+
+ /*
+ * What is done:
+ * ___ ___
+ * | | | |
+ * -> 1 -> 1
+ * | -transform-> / \
+ * 2 2 3
+ * |
+ * 3
+ *
+ */
+
+ public AbstractVersionedRecursiveBidirectionalOneToManyTest(String str) {
+ super(str);
+ }
+
+ public String[] getMappings() {
+ return new String[] { "onetomany/VersionedNode.hbm.xml" };
+ }
+
+ void check(boolean simplePropertyUpdated) {
+ super.check( simplePropertyUpdated );
+ Session s = openSession();
+ Transaction tx = s.beginTransaction();
+ Node node1 = ( Node ) s.get( Node.class, new Integer( 1 ) );
+ Node node2 = ( Node ) s.get( Node.class, new Integer( 2 ) );
+ Node node3 = ( Node ) s.get( Node.class, new Integer( 3 ) );
+ assertEquals( 1, node1.getVersion() );
+ assertEquals( 1, node2.getVersion() );
+ assertEquals( 1, node3.getVersion() );
+ tx.commit();
+ s.close();
+ }
+}
diff --git a/testsuite/src/test/java/org/hibernate/test/onetomany/Node.hbm.xml b/testsuite/src/test/java/org/hibernate/test/onetomany/Node.hbm.xml
index 102006e76d..39c6e0e0fc 100644
--- a/testsuite/src/test/java/org/hibernate/test/onetomany/Node.hbm.xml
+++ b/testsuite/src/test/java/org/hibernate/test/onetomany/Node.hbm.xml
@@ -8,6 +8,7 @@
+
diff --git a/testsuite/src/test/java/org/hibernate/test/onetomany/Node.java b/testsuite/src/test/java/org/hibernate/test/onetomany/Node.java
index 30c19c935d..07c2d2f2d8 100644
--- a/testsuite/src/test/java/org/hibernate/test/onetomany/Node.java
+++ b/testsuite/src/test/java/org/hibernate/test/onetomany/Node.java
@@ -31,15 +31,17 @@ import java.util.ArrayList;
public class Node implements Serializable {
private Integer id;
-
+ private long version;
private Node parentNode;
+ private String description;
private List subNodes = new ArrayList();
public Node() {
}
- public Node(int id) {
+ public Node(int id, String description) {
setId( id );
+ setDescription( description );
}
public Integer getId() {
@@ -50,6 +52,22 @@ public class Node implements Serializable {
this.id = id;
}
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
public Node getParentNode() {
return parentNode;
}
diff --git a/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveBidirectionalOneToManyCacheTest.java b/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveBidirectionalOneToManyCacheTest.java
index 01b9280e44..57a32e47e8 100644
--- a/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveBidirectionalOneToManyCacheTest.java
+++ b/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveBidirectionalOneToManyCacheTest.java
@@ -61,24 +61,4 @@ public class RecursiveBidirectionalOneToManyCacheTest extends AbstractRecursiveB
public static Test suite() {
return new FunctionalTestClassTestSuite( RecursiveBidirectionalOneToManyCacheTest.class );
}
-
- public void testOneToManyMoveElement() {
- reportSkip( "non-inverse one-to-many known to fail with 2nd-level cache", "cache support");
- }
-
- // HHH-2350
- public void testOneToManyMoveElementFailureExpected() {
- super.testOneToManyMoveElement();
- }
-
- public void testOneToManyReplaceList() {
- reportSkip( "non-inverse one-to-many known to fail with 2nd-level cache", "cache support");
- }
-
- // HHH-2350
- public void testOneToManyReplaceListFailureExpected() {
- super.testOneToManyReplaceList();
- }
-
-
}
diff --git a/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveVersionedBidirectionalOneToManyCacheTest.java b/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveVersionedBidirectionalOneToManyCacheTest.java
new file mode 100644
index 0000000000..90270fe00f
--- /dev/null
+++ b/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveVersionedBidirectionalOneToManyCacheTest.java
@@ -0,0 +1,64 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.onetomany;
+
+import junit.framework.Test;
+
+import org.hibernate.CacheMode;
+import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * @author Burkhard Graves, Gail Badner
+ */
+
+public class RecursiveVersionedBidirectionalOneToManyCacheTest extends AbstractVersionedRecursiveBidirectionalOneToManyTest {
+
+ /*
+ * What is done:
+ * ___ ___
+ * | | | |
+ * -> 1 -> 1
+ * | -transform-> / \
+ * 2 2 3
+ * |
+ * 3
+ *
+ * Commenting out
+ * @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
+ * in Node.java makes the assertion true (in check() below).
+ */
+
+ public RecursiveVersionedBidirectionalOneToManyCacheTest(String str) {
+ super(str);
+ }
+
+ protected CacheMode getSessionCacheMode() {
+ return CacheMode.NORMAL;
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( RecursiveVersionedBidirectionalOneToManyCacheTest.class );
+ }
+}
diff --git a/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveVersionedBidirectionalOneToManyNoCacheTest.java b/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveVersionedBidirectionalOneToManyNoCacheTest.java
new file mode 100644
index 0000000000..064b9560c4
--- /dev/null
+++ b/testsuite/src/test/java/org/hibernate/test/onetomany/RecursiveVersionedBidirectionalOneToManyNoCacheTest.java
@@ -0,0 +1,68 @@
+/*
+ * Hibernate, Relational Persistence for Idiomatic Java
+ *
+ * Copyright (c) 2010, Red Hat Middleware LLC or third-party contributors as
+ * indicated by the @author tags or express copyright attribution
+ * statements applied by the authors. All third-party contributions are
+ * distributed under license by Red Hat Middleware LLC.
+ *
+ * This copyrighted material is made available to anyone wishing to use, modify,
+ * copy, or redistribute it subject to the terms and conditions of the GNU
+ * Lesser General Public License, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this distribution; if not, write to:
+ * Free Software Foundation, Inc.
+ * 51 Franklin Street, Fifth Floor
+ * Boston, MA 02110-1301 USA
+ *
+ */
+package org.hibernate.test.onetomany;
+
+import junit.framework.Test;
+
+import org.hibernate.CacheMode;
+import org.hibernate.testing.junit.functional.FunctionalTestClassTestSuite;
+
+/**
+ * @author Burkhard Graves, Gail Badner
+ */
+
+public class RecursiveVersionedBidirectionalOneToManyNoCacheTest extends AbstractVersionedRecursiveBidirectionalOneToManyTest {
+
+ /*
+ * What is done:
+ * ___ ___
+ * | | | |
+ * -> 1 -> 1
+ * | -transform-> / \
+ * 2 2 3
+ * |
+ * 3
+ *
+ * Commenting out
+ * @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
+ * in Node.java makes the assertion true (in check() below).
+ */
+
+ public RecursiveVersionedBidirectionalOneToManyNoCacheTest(String str) {
+ super(str);
+ }
+
+ public String getCacheConcurrencyStrategy() {
+ return null;
+ }
+
+ protected CacheMode getSessionCacheMode() {
+ return CacheMode.IGNORE;
+ }
+
+ public static Test suite() {
+ return new FunctionalTestClassTestSuite( RecursiveVersionedBidirectionalOneToManyNoCacheTest.class );
+ }
+}
diff --git a/testsuite/src/test/java/org/hibernate/test/onetomany/VersionedNode.hbm.xml b/testsuite/src/test/java/org/hibernate/test/onetomany/VersionedNode.hbm.xml
new file mode 100644
index 0000000000..3784716d38
--- /dev/null
+++ b/testsuite/src/test/java/org/hibernate/test/onetomany/VersionedNode.hbm.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+