From: <hib...@li...> - 2006-06-27 21:18:39
|
Author: ste...@jb... Date: 2006-06-27 17:17:04 -0400 (Tue, 27 Jun 2006) New Revision: 10055 Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Other.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/OtherAssigned.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentInfoAssigned.java Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Child.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Parent.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml Log: full tests for HHH-1822 Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java 2006-06-27 21:17:04 UTC (rev 10055) @@ -3,13 +3,26 @@ import org.hibernate.test.jpa.AbstractJPATest; import org.hibernate.Session; import org.hibernate.TransientObjectException; -import org.hibernate.event.def.DefaultPersistOnFlushEventListener; +import org.hibernate.EntityMode; +import org.hibernate.HibernateException; +import org.hibernate.engine.Status; +import org.hibernate.persister.entity.EntityPersister; +import org.hibernate.event.FlushEntityEventListener; +import org.hibernate.event.FlushEntityEvent; import org.hibernate.cfg.Configuration; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; /** - * todo: describe CascadeTest + * According to the JPA spec, persist()ing an entity should throw an exception + * when said entity contains a reference to a transient entity through a mapped + * association where that association is not marked for cascading the persist + * operation. + * <p/> + * This test-case tests that requirement in the various association style + * scenarios such as many-to-one, one-to-one, many-to-one (property-ref), + * one-to-one (property-ref). Additionally, it performs each of these tests + * in both generated and assigned identifier usages... * * @author Steve Ebersole */ @@ -27,59 +40,301 @@ protected void configure(Configuration cfg) { super.configure( cfg ); -// cfg.setListeners( "create", new DefaultPersistOnFlushEventListener[] { new DefaultPersistOnFlushEventListener() } ); -// cfg.setListeners( "create-onflush", new DefaultPersistOnFlushEventListener[] { new DefaultPersistOnFlushEventListener() } ); } - public void testPersistOnFlushWithNoCascadeToTransientAssociation() { - // according to the JPA spec, persist()ing an entity should throw - // an exception when said entity contains a reference to a transient - // asoociation where that association is not marked for cascading - // the persist operation... - Session s = openSession(); - s.beginTransaction(); - Parent p = new Parent( "p1" ); - Child c = new Child( "c1" ); - c.setParent( p ); - s.persist( c ); + public void testManyToOneGeneratedIdsOnSave() { + // NOTES: Child defines a many-to-one back to its Parent. This + // association does not define persist cascading (which is natural; + // a child should not be able to create its parent). try { + Session s = openSession(); + s.beginTransaction(); + Parent p = new Parent( "parent" ); + Child c = new Child( "child" ); + c.setParent( p ); + s.save( c ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception", e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + public void testManyToOneGeneratedIds() { + // NOTES: Child defines a many-to-one back to its Parent. This + // association does not define persist cascading (which is natural; + // a child should not be able to create its parent). + try { + Session s = openSession(); + s.beginTransaction(); + Parent p = new Parent( "parent" ); + Child c = new Child( "child" ); + c.setParent( p ); + s.persist( c ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception", e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + public void testManyToOneAssignedIds() { + // NOTES: Child defines a many-to-one back to its Parent. This + // association does not define persist cascading (which is natural; + // a child should not be able to create its parent). + try { + Session s = openSession(); + s.beginTransaction(); + ParentAssigned p = new ParentAssigned( new Long( 1 ), "parent" ); + ChildAssigned c = new ChildAssigned( new Long( 2 ), "child" ); + c.setParent( p ); + s.persist( c ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception", e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + public void testOneToOneGeneratedIds() { + try { + Session s = openSession(); + s.beginTransaction(); + Parent p = new Parent( "parent" ); + ParentInfo info = new ParentInfo( "xyz" ); + p.setInfo( info ); + info.setOwner( p ); + s.persist( p ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception", e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + public void testOneToOneAssignedIds() { + try { + Session s = openSession(); + s.beginTransaction(); + ParentAssigned p = new ParentAssigned( new Long( 1 ), "parent" ); + ParentInfoAssigned info = new ParentInfoAssigned( "something secret" ); + p.setInfo( info ); + info.setOwner( p ); + s.persist( p ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception", e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + public void testManyToOnePropertyRefGeneratedIds() { + try { + Session s = openSession(); + s.beginTransaction(); + Parent p = new Parent( "parent" ); + Other other = new Other(); + other.setOwner( p ); + s.persist( other ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception", e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + public void testManyToOnePropertyRefAssignedIds() { + try { + Session s = openSession(); + s.beginTransaction(); + ParentAssigned p = new ParentAssigned( new Long( 1 ), "parent" ); + OtherAssigned other = new OtherAssigned( new Long( 2 ) ); + other.setOwner( p ); + s.persist( other ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception", e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + public void testOneToOnePropertyRefGeneratedIds() { + try { + Session s = openSession(); + s.beginTransaction(); + Child c2 = new Child( "c2" ); + ChildInfo info = new ChildInfo( "blah blah blah" ); + c2.setInfo( info ); + info.setOwner( c2 ); + s.persist( c2 ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception : " + e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + public void testOneToOnePropertyRefAssignedIds() { + try { + Session s = openSession(); + s.beginTransaction(); + ChildAssigned c2 = new ChildAssigned( new Long( 3 ), "c3" ); + ChildInfoAssigned info = new ChildInfoAssigned( new Long( 4 ), "blah blah blah" ); + c2.setInfo( info ); + info.setOwner( c2 ); + s.persist( c2 ); + try { + s.getTransaction().commit(); + fail( "expecting TransientObjectException on flush" ); + } + catch( TransientObjectException e ) { + // expected result + log.trace( "handled expected exception : " + e ); + s.getTransaction().rollback(); + } + finally { + s.close(); + } + } + finally { + cleanupData(); + } + } + + + private void cleanupData() { + Session s = null; + try { + s = openSession(); + s.beginTransaction(); + s.createQuery( "delete ChildInfoAssigned" ).executeUpdate(); + s.createQuery( "delete ChildAssigned" ).executeUpdate(); + s.createQuery( "delete ParentAssigned" ).executeUpdate(); + s.createQuery( "delete ChildInfoAssigned" ).executeUpdate(); + s.createQuery( "delete ChildAssigned" ).executeUpdate(); + s.createQuery( "delete ParentAssigned" ).executeUpdate(); s.getTransaction().commit(); - fail( "expecting TransientObjectException on flush" ); } - catch( TransientObjectException e ) { - // expected result - log.trace( "handled expected exception", e ); + catch( Throwable t ) { + log.warn( "unable to cleanup test data [" + fullTestName() + "] : " + t ); } - s.close(); + finally { + if ( s != null ) { + try { + s.close(); + } + catch( Throwable ignore ) { + } + } + } + } - s = openSession(); - s.beginTransaction(); - s.createQuery( "delete Child" ).executeUpdate(); - s.createQuery( "delete Parent" ).executeUpdate(); - s.getTransaction().commit(); - s.close(); + protected FlushEntityEventListener[] buildFlushEntityEventListeners() { + return new FlushEntityEventListener[] { new JPACheckingFlushEntityEventListener() }; } - public void testPersistOnFlushWithNoCascadeToTransientAssociationWithAssignedIdentifier() { - // according to the JPA spec, persist()ing an entity should throw - // an exception when said entity contains a reference to a transient - // asoociation where that association is not marked for cascading - // the persist operation... - Session s = openSession(); - s.beginTransaction(); - ParentAssigned p = new ParentAssigned( new Long( 1 ), "p1" ); - ChildAssigned c = new ChildAssigned( new Long( 2 ), "c1" ); - c.setParent( p ); - s.persist( c ); - s.getTransaction().commit(); - s.close(); + public static class JPACheckingFlushEntityEventListener extends JPAFlushEntityEventListener { + public void onFlushEntity(FlushEntityEvent event) throws HibernateException { + super.onFlushEntity( event ); //To change body of overridden methods use File | Settings | File Templates. + } - s = openSession(); - s.beginTransaction(); - s.createQuery( "delete ChildAssigned" ).executeUpdate(); - s.createQuery( "delete ParentAssigned" ).executeUpdate(); - s.getTransaction().commit(); - s.close(); + protected void validate(Object entity, EntityPersister persister, Status status, EntityMode entityMode) { + super.validate( entity, persister, status, entityMode ); + } } + + public static class JPAPersistTransientAssociationChecker { + // implements the checks required by the JPA spec regarding entities with + // non-cacaded associations to transient entities. + + } } Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Child.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Child.java 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Child.java 2006-06-27 21:17:04 UTC (rev 10055) @@ -9,6 +9,7 @@ private Long id; private String name; private Parent parent; + private ChildInfo info; public Child() { } @@ -40,4 +41,12 @@ public void setParent(Parent parent) { this.parent = parent; } + + public ChildInfo getInfo() { + return info; + } + + public void setInfo(ChildInfo info) { + this.info = info; + } } Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java 2006-06-27 21:17:04 UTC (rev 10055) @@ -9,6 +9,7 @@ private Long id; private String name; private ParentAssigned parent; + private ChildInfoAssigned info; public ChildAssigned() { } @@ -37,4 +38,12 @@ public void setParent(ParentAssigned parent) { this.parent = parent; } + + public ChildInfoAssigned getInfo() { + return info; + } + + public void setInfo(ChildInfoAssigned info) { + this.info = info; + } } Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Other.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Other.java 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Other.java 2006-06-27 21:17:04 UTC (rev 10055) @@ -0,0 +1,23 @@ +package org.hibernate.test.jpa.cascade; + +/** + * todo: describe Other + * + * @author Steve Ebersole + */ +public class Other { + private Long id; + private Parent owner; + + public Long getId() { + return id; + } + + public Parent getOwner() { + return owner; + } + + public void setOwner(Parent owner) { + this.owner = owner; + } +} Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/OtherAssigned.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/OtherAssigned.java 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/OtherAssigned.java 2006-06-27 21:17:04 UTC (rev 10055) @@ -0,0 +1,30 @@ +package org.hibernate.test.jpa.cascade; + +/** + * todo: describe Other + * + * @author Steve Ebersole + */ +public class OtherAssigned { + private Long id; + private ParentAssigned owner; + + public OtherAssigned() { + } + + public OtherAssigned(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public ParentAssigned getOwner() { + return owner; + } + + public void setOwner(ParentAssigned owner) { + this.owner = owner; + } +} Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Parent.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Parent.java 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/Parent.java 2006-06-27 21:17:04 UTC (rev 10055) @@ -8,6 +8,7 @@ public class Parent { private Long id; private String name; + private ParentInfo info; public Parent() { } @@ -31,4 +32,12 @@ public void setName(String name) { this.name = name; } + + public ParentInfo getInfo() { + return info; + } + + public void setInfo(ParentInfo info) { + this.info = info; + } } Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java 2006-06-27 21:17:04 UTC (rev 10055) @@ -8,6 +8,7 @@ public class ParentAssigned { private Long id; private String name; + private ParentInfoAssigned info; public ParentAssigned() { } @@ -28,4 +29,12 @@ public void setName(String name) { this.name = name; } + + public ParentInfoAssigned getInfo() { + return info; + } + + public void setInfo(ParentInfoAssigned info) { + this.info = info; + } } Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml 2006-06-27 21:17:04 UTC (rev 10055) @@ -4,34 +4,94 @@ <hibernate-mapping package="org.hibernate.test.jpa.cascade" default-access="field"> - <class name="Parent" table="PARENT"> + <!-- +++++++++++++ Generated ids ++++++++++++++++++++++ --> + + <class name="Parent" table="PARENT"> <id name="id" column="ID" type="long"> <generator class="increment"/> </id> - <property name="name"/> + <property name="name" type="string" unique="true"/> + <one-to-one name="info" class="ParentInfo" cascade="none"/> </class> <class name="Child" table="CHILD"> <id name="id" column="ID" type="long"> <generator class="increment"/> </id> - <property name="name"/> + <property name="name" type="string"/> <many-to-one name="parent" class="Parent" cascade="none"/> + <one-to-one name="info" property-ref="owner" class="ChildInfo" cascade="none"/> </class> - <class name="ParentAssigned" table="PARENT"> + <class name="ParentInfo" table="P_INFO"> <id name="id" column="ID" type="long"> + <generator class="foreign"> + <param name="property">owner</param> + </generator> + </id> + <property name="info" column="INFO" type="string"/> + <one-to-one name="owner" class="Parent" constrained="true" cascade="none"/> + </class> + + <class name="ChildInfo" table="C_INFO"> + <id name="id" column="ID" type="long"> + <generator class="increment"/> + </id> + <property name="info" column="INFO" type="string"/> + <many-to-one name="owner" class="Child" column="CHILD_ID" cascade="none"/> + </class> + + <class name="Other" table="OTHER"> + <id name="id" column="ID" type="long"> + <generator class="increment"/> + </id> + <many-to-one name="owner" column="OWNER_NAME" class="Parent" property-ref="name" cascade="none"/> + </class> + + + + <!-- +++++++++++++ Assigned ids ++++++++++++++++++++++ --> + + <class name="ParentAssigned" table="PARENT_A"> + <id name="id" column="ID" type="long"> <generator class="assigned"/> </id> - <property name="name"/> + <property name="name" type="string" unique="true"/> + <one-to-one name="info" class="ParentInfoAssigned"/> </class> - <class name="ChildAssigned" table="CHILD"> + <class name="ChildAssigned" table="CHILD_A"> <id name="id" column="ID" type="long"> <generator class="assigned"/> </id> - <property name="name"/> + <property name="name" type="string"/> <many-to-one name="parent" class="ParentAssigned" cascade="none"/> + <one-to-one name="info" property-ref="owner" class="ChildInfoAssigned" cascade="none"/> </class> + <class name="ParentInfoAssigned" table="P_INFO_A"> + <id name="id" column="ID" type="long"> + <generator class="foreign"> + <param name="property">owner</param> + </generator> + </id> + <property name="info" column="INFO" type="string"/> + <one-to-one name="owner" class="ParentAssigned" constrained="true"/> + </class> + + <class name="ChildInfoAssigned" table="C_INFO_A"> + <id name="id" column="ID" type="long"> + <generator class="assigned"/> + </id> + <property name="info" column="INFO" type="string"/> + <many-to-one name="owner" class="ChildAssigned" column="CHILD_ID" cascade="none"/> + </class> + + <class name="OtherAssigned" table="OTHER_A"> + <id name="id" column="ID" type="long"> + <generator class="assigned"/> + </id> + <many-to-one name="owner" column="OWNER_NAME" class="ParentAssigned" property-ref="name" cascade="none"/> + </class> + </hibernate-mapping> \ No newline at end of file Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentInfoAssigned.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentInfoAssigned.java 2006-06-27 21:12:17 UTC (rev 10054) +++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentInfoAssigned.java 2006-06-27 21:17:04 UTC (rev 10055) @@ -0,0 +1,39 @@ +package org.hibernate.test.jpa.cascade; + +/** + * todo: describe ChildInfo + * + * @author Steve Ebersole + */ +public class ParentInfoAssigned { + private Long id; + private ParentAssigned owner; + private String info; + + public ParentInfoAssigned() { + } + + public ParentInfoAssigned(String info) { + this.info = info; + } + + public Long getId() { + return id; + } + + public ParentAssigned getOwner() { + return owner; + } + + public void setOwner(ParentAssigned owner) { + this.owner = owner; + } + + public String getInfo() { + return info; + } + + public void setInfo(String info) { + this.info = info; + } +} |