HHH-2711 : composite-map-key + unidir map can lead to PropertyAccessException
git-svn-id: https://svn.jboss.org/repos/hibernate/core/branches/Branch_3_2@12860 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
c23b920ff8
commit
5f392deeae
11
build.xml
11
build.xml
|
@ -99,6 +99,9 @@
|
||||||
<exclude name="**/*.hbm.xml" />
|
<exclude name="**/*.hbm.xml" />
|
||||||
</patternset>
|
</patternset>
|
||||||
|
|
||||||
|
<!-- Define default test suite parameters -->
|
||||||
|
<property name="hibernate.junit.forkmode" value="perBatch"/>
|
||||||
|
<property name="hibernate.junit.timeout" value="2147483647"/>
|
||||||
|
|
||||||
<!-- ################################################################## -->
|
<!-- ################################################################## -->
|
||||||
<!-- ############################# Tasks ############################## -->
|
<!-- ############################# Tasks ############################## -->
|
||||||
|
@ -283,7 +286,7 @@
|
||||||
<pathelement path="${dir.props}"/>
|
<pathelement path="${dir.props}"/>
|
||||||
</path>
|
</path>
|
||||||
|
|
||||||
<junit printsummary="yes" dir="${basedir}" maxmemory="256M" fork="yes" forkmode="perBatch">
|
<junit printsummary="yes" dir="${basedir}" maxmemory="256M" fork="yes" forkmode="${hibernate.junit.forkmode}" timeout="${hibernate.junit.timeout}">
|
||||||
<jvmarg value="-Dhibernate.test.validatefailureexpected=${hibernate.test.validatefailureexpected}"/>
|
<jvmarg value="-Dhibernate.test.validatefailureexpected=${hibernate.test.validatefailureexpected}"/>
|
||||||
<classpath>
|
<classpath>
|
||||||
<fileset refid="fs.lib" />
|
<fileset refid="fs.lib" />
|
||||||
|
@ -311,7 +314,7 @@
|
||||||
|
|
||||||
<target name="junit.instrument.cglib" depends="instrument.cglib">
|
<target name="junit.instrument.cglib" depends="instrument.cglib">
|
||||||
<mkdir dir="${dir.out.junit}"/>
|
<mkdir dir="${dir.out.junit}"/>
|
||||||
<junit printsummary="yes" maxmemory="256M" fork="yes">
|
<junit printsummary="yes" maxmemory="256M" fork="yes" timeout="${hibernate.junit.timeout}">
|
||||||
<jvmarg value="-Dhibernate.test.validatefailureexpected=${hibernate.test.validatefailureexpected}"/>
|
<jvmarg value="-Dhibernate.test.validatefailureexpected=${hibernate.test.validatefailureexpected}"/>
|
||||||
<classpath>
|
<classpath>
|
||||||
<fileset refid="fs.lib" />
|
<fileset refid="fs.lib" />
|
||||||
|
@ -333,7 +336,7 @@
|
||||||
|
|
||||||
<target name="junit.instrument.javassist" depends="instrument.javassist">
|
<target name="junit.instrument.javassist" depends="instrument.javassist">
|
||||||
<mkdir dir="${dir.out.junit}"/>
|
<mkdir dir="${dir.out.junit}"/>
|
||||||
<junit printsummary="yes" maxmemory="256M" fork="yes">
|
<junit printsummary="yes" maxmemory="256M" fork="yes" timeout="${hibernate.junit.timeout}">
|
||||||
<jvmarg value="-Dhibernate.test.validatefailureexpected=${hibernate.test.validatefailureexpected}"/>
|
<jvmarg value="-Dhibernate.test.validatefailureexpected=${hibernate.test.validatefailureexpected}"/>
|
||||||
<classpath>
|
<classpath>
|
||||||
<fileset refid="fs.lib" />
|
<fileset refid="fs.lib" />
|
||||||
|
@ -357,7 +360,7 @@
|
||||||
<target name="junitsingle" depends="cleantestdb,compiletest" description="Run a single test suite (requires testname and jar.driver properties)">
|
<target name="junitsingle" depends="cleantestdb,compiletest" description="Run a single test suite (requires testname and jar.driver properties)">
|
||||||
<delete dir="${dir.out.junit}"/>
|
<delete dir="${dir.out.junit}"/>
|
||||||
<mkdir dir="${dir.out.junit}"/>
|
<mkdir dir="${dir.out.junit}"/>
|
||||||
<junit printsummary="yes" fork="yes" haltonfailure="yes" dir="${basedir}">
|
<junit printsummary="yes" fork="yes" haltonfailure="yes" dir="${basedir}" timeout="${hibernate.junit.timeout}">
|
||||||
<classpath>
|
<classpath>
|
||||||
<fileset refid="fs.lib" />
|
<fileset refid="fs.lib" />
|
||||||
<path refid="path.jdbc" />
|
<path refid="path.jdbc" />
|
||||||
|
|
|
@ -1,25 +1,25 @@
|
||||||
//$Id: PojoComponentTuplizer.java 9619 2006-03-15 00:12:47Z steve.ebersole@jboss.com $
|
//$Id: PojoComponentTuplizer.java 9619 2006-03-15 00:12:47Z steve.ebersole@jboss.com $
|
||||||
package org.hibernate.tuple.component;
|
package org.hibernate.tuple.component;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.tuple.component.AbstractComponentTuplizer;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.tuple.Instantiator;
|
|
||||||
import org.hibernate.tuple.PojoInstantiator;
|
|
||||||
import org.hibernate.util.ReflectHelper;
|
|
||||||
import org.hibernate.bytecode.ReflectionOptimizer;
|
|
||||||
import org.hibernate.bytecode.BasicProxyFactory;
|
import org.hibernate.bytecode.BasicProxyFactory;
|
||||||
|
import org.hibernate.bytecode.ReflectionOptimizer;
|
||||||
import org.hibernate.cfg.Environment;
|
import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.engine.SessionFactoryImplementor;
|
import org.hibernate.engine.SessionFactoryImplementor;
|
||||||
import org.hibernate.mapping.Component;
|
import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.Property;
|
import org.hibernate.mapping.Property;
|
||||||
|
import org.hibernate.property.BackrefPropertyAccessor;
|
||||||
import org.hibernate.property.Getter;
|
import org.hibernate.property.Getter;
|
||||||
import org.hibernate.property.PropertyAccessor;
|
import org.hibernate.property.PropertyAccessor;
|
||||||
import org.hibernate.property.PropertyAccessorFactory;
|
import org.hibernate.property.PropertyAccessorFactory;
|
||||||
import org.hibernate.property.Setter;
|
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.
|
* A {@link ComponentTuplizer} specific to the pojo entity mode.
|
||||||
|
@ -76,6 +76,9 @@ public class PojoComponentTuplizer extends AbstractComponentTuplizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] getPropertyValues(Object component) throws HibernateException {
|
public Object[] getPropertyValues(Object component) throws HibernateException {
|
||||||
|
if ( component == BackrefPropertyAccessor.UNKNOWN ) {
|
||||||
|
return new Object[ propertySpan ];
|
||||||
|
}
|
||||||
if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
if ( optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
||||||
return optimizer.getAccessOptimizer().getPropertyValues( component );
|
return optimizer.getAccessOptimizer().getPropertyValues( component );
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.hibernate.test.collection;
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
import junit.framework.TestSuite;
|
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.bag.PersistentBagTest;
|
||||||
import org.hibernate.test.collection.idbag.PersistentIdBagTest;
|
import org.hibernate.test.collection.idbag.PersistentIdBagTest;
|
||||||
import org.hibernate.test.collection.list.PersistentListTest;
|
import org.hibernate.test.collection.list.PersistentListTest;
|
||||||
|
@ -25,6 +26,7 @@ public class CollectionSuite {
|
||||||
suite.addTest( PersistentMapTest.suite() );
|
suite.addTest( PersistentMapTest.suite() );
|
||||||
suite.addTest( CollectionTest.suite() );
|
suite.addTest( CollectionTest.suite() );
|
||||||
suite.addTest( PersistentSetTest.suite() );
|
suite.addTest( PersistentSetTest.suite() );
|
||||||
|
suite.addTest( BackrefCompositeMapKeyTest.suite() );
|
||||||
return suite;
|
return suite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
}
|
|
@ -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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue