[hibernate-commits] Hibernate SVN: r12860 - in core/branches/Branch_3_2: test/org/hibernate/test/collection and 3 other directories.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Tue Jul 31 09:39:45 EDT 2007


Author: steve.ebersole at jboss.com
Date: 2007-07-31 09:39:45 -0400 (Tue, 31 Jul 2007)
New Revision: 12860

Added:
   core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/
   core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/
   core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/
   core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/BackrefCompositeMapKeyTest.java
   core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/MapKey.java
   core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Mappings.hbm.xml
   core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Part.java
   core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Product.java
Modified:
   core/branches/Branch_3_2/src/org/hibernate/tuple/component/PojoComponentTuplizer.java
   core/branches/Branch_3_2/test/org/hibernate/test/collection/CollectionSuite.java
Log:
HHH-2711 : composite-map-key + unidir map can lead to PropertyAccessException

Modified: core/branches/Branch_3_2/src/org/hibernate/tuple/component/PojoComponentTuplizer.java
===================================================================
--- core/branches/Branch_3_2/src/org/hibernate/tuple/component/PojoComponentTuplizer.java	2007-07-31 13:39:23 UTC (rev 12859)
+++ core/branches/Branch_3_2/src/org/hibernate/tuple/component/PojoComponentTuplizer.java	2007-07-31 13:39:45 UTC (rev 12860)
@@ -1,25 +1,25 @@
 //$Id: PojoComponentTuplizer.java 9619 2006-03-15 00:12:47Z steve.ebersole at jboss.com $
 package org.hibernate.tuple.component;
 
+import java.io.Serializable;
 import java.lang.reflect.Method;
-import java.io.Serializable;
 
+import org.hibernate.AssertionFailure;
 import org.hibernate.HibernateException;
-import org.hibernate.AssertionFailure;
-import org.hibernate.tuple.component.AbstractComponentTuplizer;
-import org.hibernate.tuple.Instantiator;
-import org.hibernate.tuple.PojoInstantiator;
-import org.hibernate.util.ReflectHelper;
+import org.hibernate.bytecode.BasicProxyFactory;
 import org.hibernate.bytecode.ReflectionOptimizer;
-import org.hibernate.bytecode.BasicProxyFactory;
 import org.hibernate.cfg.Environment;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.mapping.Component;
 import org.hibernate.mapping.Property;
+import org.hibernate.property.BackrefPropertyAccessor;
 import org.hibernate.property.Getter;
 import org.hibernate.property.PropertyAccessor;
 import org.hibernate.property.PropertyAccessorFactory;
 import org.hibernate.property.Setter;
+import org.hibernate.tuple.Instantiator;
+import org.hibernate.tuple.PojoInstantiator;
+import org.hibernate.util.ReflectHelper;
 
 /**
  * A {@link ComponentTuplizer} specific to the pojo entity mode.
@@ -76,6 +76,9 @@
 	}
 
 	public Object[] getPropertyValues(Object component) throws HibernateException {
+		if ( component == BackrefPropertyAccessor.UNKNOWN ) {
+			return new Object[ propertySpan ];
+		}
 		if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
 			return optimizer.getAccessOptimizer().getPropertyValues( component );
 		}

Modified: core/branches/Branch_3_2/test/org/hibernate/test/collection/CollectionSuite.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/collection/CollectionSuite.java	2007-07-31 13:39:23 UTC (rev 12859)
+++ core/branches/Branch_3_2/test/org/hibernate/test/collection/CollectionSuite.java	2007-07-31 13:39:45 UTC (rev 12860)
@@ -3,6 +3,7 @@
 import junit.framework.Test;
 import junit.framework.TestSuite;
 
+import org.hibernate.test.collection.backref.map.compkey.BackrefCompositeMapKeyTest;
 import org.hibernate.test.collection.bag.PersistentBagTest;
 import org.hibernate.test.collection.idbag.PersistentIdBagTest;
 import org.hibernate.test.collection.list.PersistentListTest;
@@ -25,6 +26,7 @@
 		suite.addTest( PersistentMapTest.suite() );
 		suite.addTest( CollectionTest.suite() );
 		suite.addTest( PersistentSetTest.suite() );
+		suite.addTest( BackrefCompositeMapKeyTest.suite() );
 		return suite;
 	}
 

Added: core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/BackrefCompositeMapKeyTest.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/BackrefCompositeMapKeyTest.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/BackrefCompositeMapKeyTest.java	2007-07-31 13:39:45 UTC (rev 12860)
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.test.collection.backref.map.compkey;
+
+import junit.framework.Test;
+
+import org.hibernate.junit.functional.FunctionalTestCase;
+import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.LockMode;
+import org.hibernate.Hibernate;
+import org.hibernate.util.SerializationHelper;
+
+/**
+ * BackrefCompositeMapKeyTest implementation.  Test access to a composite map-key
+ * backref via a number of different access methods.
+ *
+ * @author Steve Ebersole
+ */
+public class BackrefCompositeMapKeyTest extends FunctionalTestCase {
+	public BackrefCompositeMapKeyTest(String string) {
+		super( string );
+	}
+
+	public String[] getMappings() {
+		return new String[] { "collection/backref/map/compkey/Mappings.hbm.xml" };
+	}
+
+	public static Test suite() {
+		return new FunctionalTestClassTestSuite( BackrefCompositeMapKeyTest.class );
+	}
+
+	public void testOrphanDeleteOnDelete() {
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		Product prod = new Product( "Widget" );
+		Part part = new Part( "Widge", "part if a Widget" );
+		MapKey mapKey = new MapKey( "Top" );
+		prod.getParts().put( mapKey, part );
+		Part part2 = new Part( "Get", "another part if a Widget" );
+		prod.getParts().put( new MapKey( "Bottom" ), part2 );
+		session.persist( prod );
+		session.flush();
+
+		prod.getParts().remove( mapKey );
+
+		session.delete( prod );
+
+		t.commit();
+		session.close();
+
+		session = openSession();
+		t = session.beginTransaction();
+		assertNull( "Orphan 'Widge' was not deleted", session.get(Part.class, "Widge") );
+		assertNull( "Orphan 'Get' was not deleted", session.get(Part.class, "Get") );
+		assertNull( "Orphan 'Widget' was not deleted", session.get(Product.class, "Widget") );
+		t.commit();
+		session.close();
+	}
+
+	public void testOrphanDeleteAfterPersist() {
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		Product prod = new Product( "Widget" );
+		Part part = new Part( "Widge", "part if a Widget" );
+		MapKey mapKey = new MapKey( "Top" );
+		prod.getParts().put( mapKey, part );
+		Part part2 = new Part( "Get", "another part if a Widget" );
+		prod.getParts().put( new MapKey( "Bottom" ), part2 );
+		session.persist( prod );
+
+		prod.getParts().remove( mapKey );
+
+		t.commit();
+		session.close();
+
+		session = openSession();
+		t = session.beginTransaction();
+		session.delete( session.get(Product.class, "Widget") );
+		t.commit();
+		session.close();
+	}
+
+	public void testOrphanDeleteAfterPersistAndFlush() {
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		Product prod = new Product( "Widget" );
+		Part part = new Part( "Widge", "part if a Widget" );
+		MapKey mapKey = new MapKey( "Top" );
+		prod.getParts().put( mapKey, part );
+		Part part2 = new Part( "Get", "another part if a Widget" );
+		prod.getParts().put( new MapKey( "Bottom" ), part2 );
+		session.persist( prod );
+		session.flush();
+
+		prod.getParts().remove( mapKey );
+
+		t.commit();
+		session.close();
+
+		session = openSession();
+		t = session.beginTransaction();
+		assertNull( session.get(Part.class, "Widge") );
+		assertNotNull( session.get(Part.class, "Get") );
+		session.delete( session.get(Product.class, "Widget") );
+		t.commit();
+		session.close();
+	}
+
+	public void testOrphanDeleteAfterLock() {
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		Product prod = new Product( "Widget" );
+		Part part = new Part( "Widge", "part if a Widget" );
+		MapKey mapKey = new MapKey( "Top" );
+		prod.getParts().put( mapKey, part );
+		Part part2 = new Part( "Get", "another part if a Widget" );
+		prod.getParts().put( new MapKey( "Bottom" ),part2 );
+		session.persist( prod );
+		t.commit();
+		session.close();
+
+
+		session = openSession();
+		t = session.beginTransaction();
+		session.lock(prod, LockMode.READ);
+		prod.getParts().remove(mapKey);
+		t.commit();
+		session.close();
+
+		session = openSession();
+		t = session.beginTransaction();
+		assertNull( session.get(Part.class, "Widge") );
+		assertNotNull( session.get(Part.class, "Get") );
+		session.delete( session.get(Product.class, "Widget") );
+		t.commit();
+		session.close();
+	}
+
+	public void testOrphanDeleteOnSaveOrUpdate() {
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		Product prod = new Product( "Widget" );
+		Part part = new Part( "Widge", "part if a Widget" );
+		MapKey mapKey = new MapKey( "Top" );
+		prod.getParts().put( mapKey, part );
+		Part part2 = new Part( "Get", "another part if a Widget" );
+		prod.getParts().put( new MapKey( "Bottom" ), part2 );
+		session.persist( prod );
+		t.commit();
+		session.close();
+
+		prod.getParts().remove( mapKey );
+
+		session = openSession();
+		t = session.beginTransaction();
+		session.saveOrUpdate(prod);
+		t.commit();
+		session.close();
+
+		session = openSession();
+		t = session.beginTransaction();
+		assertNull( session.get(Part.class, "Widge") );
+		assertNotNull( session.get(Part.class, "Get") );
+		session.delete( session.get(Product.class, "Widget") );
+		t.commit();
+		session.close();
+	}
+
+	public void testOrphanDeleteOnSaveOrUpdateAfterSerialization() {
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		Product prod = new Product( "Widget" );
+		Part part = new Part( "Widge", "part if a Widget" );
+		MapKey mapKey = new MapKey( "Top" );
+		prod.getParts().put( mapKey, part );
+		Part part2 = new Part( "Get", "another part if a Widget" );
+		prod.getParts().put( new MapKey( "Bottom" ), part2 );
+		session.persist( prod );
+		t.commit();
+		session.close();
+
+		prod.getParts().remove( mapKey );
+
+		prod = (Product) SerializationHelper.clone( prod );
+
+		session = openSession();
+		t = session.beginTransaction();
+		session.saveOrUpdate(prod);
+		t.commit();
+		session.close();
+
+		session = openSession();
+		t = session.beginTransaction();
+		assertNull( session.get(Part.class, "Widge") );
+		assertNotNull( session.get(Part.class, "Get") );
+		session.delete( session.get(Product.class, "Widget") );
+		t.commit();
+		session.close();
+	}
+
+	public void testOrphanDelete() {
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		Product prod = new Product( "Widget" );
+		Part part = new Part( "Widge", "part if a Widget" );
+		MapKey mapKey = new MapKey( "Top" );
+		prod.getParts().put( mapKey, part );
+		Part part2 = new Part( "Get", "another part if a Widget" );
+		prod.getParts().put( new MapKey( "Bottom" ), part2 );
+		session.persist( prod );
+		t.commit();
+		session.close();
+
+		getSessions().evict(Product.class);
+		getSessions().evict(Part.class);
+
+		session = openSession();
+		t = session.beginTransaction();
+		prod = (Product) session.get(Product.class, "Widget");
+		assertTrue( Hibernate.isInitialized( prod.getParts() ) );
+		part = (Part) session.get(Part.class, "Widge");
+		prod.getParts().remove(mapKey);
+		t.commit();
+		session.close();
+
+		getSessions().evict(Product.class);
+		getSessions().evict(Part.class);
+
+		session = openSession();
+		t = session.beginTransaction();
+		prod = (Product) session.get(Product.class, "Widget");
+		assertTrue( Hibernate.isInitialized( prod.getParts() ) );
+		assertNull( prod.getParts().get(new MapKey("Top")));
+		assertNotNull( session.get(Part.class, "Get") );
+		session.delete( session.get(Product.class, "Widget") );
+		t.commit();
+		session.close();
+	}
+
+	public void testOrphanDeleteOnMerge() {
+		Session session = openSession();
+		Transaction t = session.beginTransaction();
+		Product prod = new Product( "Widget" );
+		Part part = new Part( "Widge", "part if a Widget" );
+		MapKey mapKey = new MapKey( "Top" );
+		prod.getParts().put( mapKey, part );
+		Part part2 = new Part( "Get", "another part if a Widget" );
+		prod.getParts().put( new MapKey("Bottom"), part2 );
+		session.persist( prod );
+		t.commit();
+		session.close();
+
+		prod.getParts().remove( mapKey );
+
+		session = openSession();
+		t = session.beginTransaction();
+		session.merge(prod);
+		t.commit();
+		session.close();
+
+		session = openSession();
+		t = session.beginTransaction();
+		assertNull( session.get(Part.class, "Widge") );
+		assertNotNull( session.get(Part.class, "Get") );
+		session.delete( session.get(Product.class, "Widget") );
+		t.commit();
+		session.close();
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/MapKey.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/MapKey.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/MapKey.java	2007-07-31 13:39:45 UTC (rev 12860)
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.test.collection.backref.map.compkey;
+
+import java.io.Serializable;
+
+/**
+ * A composite map key.
+ *
+ * @author Steve Ebersole
+ */
+public class MapKey implements Serializable {
+	private String role;
+
+	public MapKey() {
+	}
+
+	public MapKey(String role) {
+		this.role = role;
+	}
+
+	public String getRole() {
+		return role;
+	}
+
+	public boolean equals(Object o) {
+		if ( this == o ) {
+			return true;
+		}
+		if ( o == null || getClass() != o.getClass() ) {
+			return false;
+		}
+
+		MapKey mapKey = ( MapKey ) o;
+
+		if ( !role.equals( mapKey.role ) ) {
+			return false;
+		}
+
+		return true;
+	}
+
+	public int hashCode() {
+		return role.hashCode();
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Mappings.hbm.xml
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Mappings.hbm.xml	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Mappings.hbm.xml	2007-07-31 13:39:45 UTC (rev 12860)
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+<!--
+  ~ Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+  ~
+  ~ 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, v. 2.1. This program is distributed in the
+  ~ hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+  ~ distribution; if not, write to the Free Software Foundation, Inc.,
+  ~ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+  ~
+  ~ Red Hat Author(s): Steve Ebersole
+  -->
+<!DOCTYPE hibernate-mapping PUBLIC
+        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
+        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
+
+<!--
+    Demonstrates a unidirectional map mapping where the map key is a
+    composite.  The unidirectional collection forces Hibernate to use
+    a backref.  We want to make sure the backref works properly with
+    the component.
+-->
+<hibernate-mapping package="org.hibernate.test.collection.backref.map.compkey" default-access="field">
+
+    <class name="Product" table="t_product">
+        <id name="name"/>
+        <map name="parts" table="Parts" cascade="all,delete-orphan" fetch="join">
+            <key column="productName" not-null="true"/>
+            <composite-map-key class="MapKey">
+                <key-property name="role"/>
+            </composite-map-key>
+            <one-to-many class="Part"/>
+        </map>
+    </class>
+
+    <class name="Part" table="t_part">
+        <id name="name"/>
+        <property name="description" not-null="true"/>
+    </class>
+
+</hibernate-mapping>
\ No newline at end of file

Added: core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Part.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Part.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Part.java	2007-07-31 13:39:45 UTC (rev 12860)
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.test.collection.backref.map.compkey;
+
+import java.io.Serializable;
+
+/**
+ * Part implementation
+ *
+ * @author Steve Ebersole
+ */
+public class Part implements Serializable {
+	private String name;
+	private String description;
+
+	public Part() {
+	}
+
+	public Part(String name) {
+		this.name = name;
+	}
+
+	public Part(String name, String description) {
+		this.name = name;
+		this.description = description;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(String description) {
+		this.description = description;
+	}
+}

Added: core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Product.java
===================================================================
--- core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Product.java	                        (rev 0)
+++ core/branches/Branch_3_2/test/org/hibernate/test/collection/backref/map/compkey/Product.java	2007-07-31 13:39:45 UTC (rev 12860)
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2007, Red Hat Middleware, LLC. All rights reserved.
+ *
+ * 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, v. 2.1. This program is distributed in the
+ * hope that it will be useful, but WITHOUT A 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, v.2.1 along with this
+ * distribution; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Red Hat Author(s): Steve Ebersole
+ */
+package org.hibernate.test.collection.backref.map.compkey;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Product implementation
+ *
+ * @author Steve Ebersole
+ */
+public class Product implements Serializable {
+	private String name;
+	private Map parts = new HashMap();
+
+	public Product() {
+	}
+
+	public Product(String name) {
+		this.name = name;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Map getParts() {
+		return parts;
+	}
+
+	public void setParts(Map parts) {
+		this.parts = parts;
+	}
+}




More information about the hibernate-commits mailing list