|
From: <hib...@li...> - 2006-06-09 17:47:56
|
Author: ste...@jb...
Date: 2006-06-09 13:46:51 -0400 (Fri, 09 Jun 2006)
New Revision: 10008
Added:
trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java
trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java
Modified:
trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java
trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java
trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java
trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml
Log:
persist() with non-cascaded associations to transient objects with assigned identifier strategies
Modified: trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java 2006-06-09 17:44:51 UTC (rev 10007)
+++ trunk/Hibernate3/src/org/hibernate/engine/ForeignKeys.java 2006-06-09 17:46:51 UTC (rev 10008)
@@ -210,16 +210,18 @@
return null;
}
else {
- Serializable id = session.getContextEntityIdentifier(object);
- if ( id==null ) {
- if ( isTransient(entityName, object, Boolean.FALSE, session) ) {
+ Serializable id = session.getContextEntityIdentifier( object );
+ if ( id == null ) {
+ // context-entity-identifier returns null explicitly if the entity
+ // is not associated with the persistence context; so make some
+ // deeper checks...
+ if ( isTransient(entityName, object, null, session) ) {
throw new TransientObjectException(
"object references an unsaved transient instance - save the transient instance before flushing: " +
entityName == null ? session.guessEntityName( object ) : entityName
);
}
- id = session.getEntityPersister(entityName, object)
- .getIdentifier( object, session.getEntityMode() );
+ id = session.getEntityPersister( entityName, object ).getIdentifier( object, session.getEntityMode() );
}
return id;
}
Modified: trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java
===================================================================
--- trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java 2006-06-09 17:44:51 UTC (rev 10007)
+++ trunk/Hibernate3/src/org/hibernate/persister/collection/AbstractCollectionPersister.java 2006-06-09 17:46:51 UTC (rev 10008)
@@ -19,6 +19,7 @@
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.QueryException;
+import org.hibernate.TransientObjectException;
import org.hibernate.cache.CacheConcurrencyStrategy;
import org.hibernate.cache.CacheException;
import org.hibernate.cache.entry.CacheEntryStructure;
@@ -33,6 +34,7 @@
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.engine.SubselectFetch;
+import org.hibernate.engine.ForeignKeys;
import org.hibernate.exception.JDBCExceptionHelper;
import org.hibernate.exception.SQLExceptionConverter;
import org.hibernate.id.IdentifierGenerator;
@@ -1582,6 +1584,9 @@
rs.close();
}
}
+ catch( TransientObjectException e ) {
+ return false;
+ }
finally {
session.getBatcher().closeStatement( st );
}
Modified: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java 2006-06-09 17:44:51 UTC (rev 10007)
+++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/CascadeTest.java 2006-06-09 17:46:51 UTC (rev 10008)
@@ -2,8 +2,11 @@
import org.hibernate.test.jpa.AbstractJPATest;
import org.hibernate.Session;
+import org.hibernate.TransientObjectException;
import org.hibernate.event.def.DefaultPersistOnFlushEventListener;
import org.hibernate.cfg.Configuration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
/**
* todo: describe CascadeTest
@@ -11,6 +14,9 @@
* @author Steve Ebersole
*/
public class CascadeTest extends AbstractJPATest {
+
+ public static final Log log = LogFactory.getLog( CascadeTest.class );
+
public CascadeTest(String name) {
super( name );
}
@@ -37,7 +43,14 @@
Child c = new Child( "c1" );
c.setParent( p );
s.persist( c );
- s.getTransaction().commit();
+ try {
+ s.getTransaction().commit();
+ fail( "expecting TransientObjectException on flush" );
+ }
+ catch( TransientObjectException e ) {
+ // expected result
+ log.trace( "handled expected exception", e );
+ }
s.close();
s = openSession();
@@ -47,4 +60,26 @@
s.getTransaction().commit();
s.close();
}
+
+ 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();
+
+ s = openSession();
+ s.beginTransaction();
+ s.createQuery( "delete ChildAssigned" ).executeUpdate();
+ s.createQuery( "delete ParentAssigned" ).executeUpdate();
+ s.getTransaction().commit();
+ s.close();
+ }
}
Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java 2006-06-09 17:44:51 UTC (rev 10007)
+++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ChildAssigned.java 2006-06-09 17:46:51 UTC (rev 10008)
@@ -0,0 +1,40 @@
+package org.hibernate.test.jpa.cascade;
+
+/**
+ * Child, but with an assigned identifier.
+ *
+ * @author Steve Ebersole
+ */
+public class ChildAssigned {
+ private Long id;
+ private String name;
+ private ParentAssigned parent;
+
+ public ChildAssigned() {
+ }
+
+ public ChildAssigned(Long id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public ParentAssigned getParent() {
+ return parent;
+ }
+
+ public void setParent(ParentAssigned parent) {
+ this.parent = parent;
+ }
+}
Added: trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java
===================================================================
--- trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java 2006-06-09 17:44:51 UTC (rev 10007)
+++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentAssigned.java 2006-06-09 17:46:51 UTC (rev 10008)
@@ -0,0 +1,31 @@
+package org.hibernate.test.jpa.cascade;
+
+/**
+ * Parent, but with an assigned identifier.
+ *
+ * @author Steve Ebersole
+ */
+public class ParentAssigned {
+ private Long id;
+ private String name;
+
+ public ParentAssigned() {
+ }
+
+ public ParentAssigned(Long id, String name) {
+ this.id = id;
+ this.name = name;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
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-09 17:44:51 UTC (rev 10007)
+++ trunk/Hibernate3/test/org/hibernate/test/jpa/cascade/ParentChild.hbm.xml 2006-06-09 17:46:51 UTC (rev 10008)
@@ -2,7 +2,7 @@
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
-<hibernate-mapping package="org.hibernate.test.jpa.cascade">
+<hibernate-mapping package="org.hibernate.test.jpa.cascade" default-access="field">
<class name="Parent" table="PARENT">
<id name="id" column="ID" type="long">
@@ -19,4 +19,19 @@
<many-to-one name="parent" class="Parent" cascade="none"/>
</class>
+ <class name="ParentAssigned" table="PARENT">
+ <id name="id" column="ID" type="long">
+ <generator class="assigned"/>
+ </id>
+ <property name="name"/>
+ </class>
+
+ <class name="ChildAssigned" table="CHILD">
+ <id name="id" column="ID" type="long">
+ <generator class="assigned"/>
+ </id>
+ <property name="name"/>
+ <many-to-one name="parent" class="ParentAssigned" cascade="none"/>
+ </class>
+
</hibernate-mapping>
\ No newline at end of file
|