[hibernate-commits] Hibernate SVN: r18767 - in core/trunk: core/src/main/java/org/hibernate/event/def and 1 other directory.
hibernate-commits at lists.jboss.org
hibernate-commits at lists.jboss.org
Wed Feb 10 12:38:59 EST 2010
Author: steve.ebersole at jboss.com
Date: 2010-02-10 12:38:59 -0500 (Wed, 10 Feb 2010)
New Revision: 18767
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/DerivedIdentitySimpleParentSimpleDepMapsIdTest.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/MedicalHistory.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/Person.java
core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java
Log:
HHH-4902 - Handle JPA 2 requirement of setting id attribute to non-null with its equivalent of foreign-generator
Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/DerivedIdentitySimpleParentSimpleDepMapsIdTest.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/DerivedIdentitySimpleParentSimpleDepMapsIdTest.java 2010-02-10 17:34:16 UTC (rev 18766)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/DerivedIdentitySimpleParentSimpleDepMapsIdTest.java 2010-02-10 17:38:59 UTC (rev 18767)
@@ -1,7 +1,11 @@
package org.hibernate.test.annotations.derivedidentities.e4.b;
import java.util.Date;
+import java.util.List;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityTransaction;
+
import org.hibernate.Session;
import org.hibernate.test.annotations.TestCase;
import org.hibernate.test.util.SchemaUtil;
@@ -61,6 +65,45 @@
s.close();
}
+ public void testExplicitlyAssignedDependentIdAttributeValue() {
+ // even though the id is by definition generated (using the "foreign" strategy), JPA
+ // still does allow manually setting the generated id attribute value which providers
+ // are expected to promptly disregard :?
+ Session s = openSession();
+ s.beginTransaction();
+ Person person = new Person( "123456789" );
+ MedicalHistory medicalHistory = new MedicalHistory( "987654321", person );
+ s.persist( person );
+ s.persist( medicalHistory );
+ s.getTransaction().commit();
+ s.close();
+
+ // again, even though we specified an id value of "987654321" prior to persist,
+ // Hibernate should have replaced that with the "123456789" from the associated
+ // person
+ assertEquals( person.ssn, medicalHistory.patient.ssn );
+ assertEquals( person, medicalHistory.patient );
+ assertEquals( person.ssn, medicalHistory.id );
+
+ s = openSession();
+ s.beginTransaction();
+ // Should return null...
+ MedicalHistory separateMedicalHistory = (MedicalHistory) s.get( MedicalHistory.class, "987654321" );
+ assertNull( separateMedicalHistory );
+ // Now we should find it...
+ separateMedicalHistory = (MedicalHistory) s.get( MedicalHistory.class, "123456789" );
+ assertNotNull( separateMedicalHistory );
+ s.getTransaction().commit();
+ s.close();
+
+ s = openSession();
+ s.beginTransaction();
+ s.delete( medicalHistory );
+ s.delete( person );
+ s.getTransaction().commit();
+ s.close();
+ }
+
@Override
protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] {
Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/MedicalHistory.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/MedicalHistory.java 2010-02-10 17:34:16 UTC (rev 18766)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/MedicalHistory.java 2010-02-10 17:38:59 UTC (rev 18767)
@@ -1,6 +1,7 @@
package org.hibernate.test.annotations.derivedidentities.e4.b;
import java.util.Date;
+import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
@@ -16,11 +17,20 @@
public class MedicalHistory {
@Id String id; // overriding not allowed ... // default join column name is overridden @MapsId
+
+ @MapsId
+ @JoinColumn(name = "FK")
+ @OneToOne(cascade= CascadeType.ALL)
+ Person patient;
+
@Temporal(TemporalType.DATE)
Date lastupdate;
- @JoinColumn(name = "FK")
- @MapsId
- @OneToOne
- Person patient;
+ public MedicalHistory() {
+ }
+
+ public MedicalHistory(String id, Person patient) {
+ this.id = id;
+ this.patient = patient;
+ }
}
Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/Person.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/Person.java 2010-02-10 17:34:16 UTC (rev 18766)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/Person.java 2010-02-10 17:38:59 UTC (rev 18767)
@@ -10,4 +10,11 @@
public class Person {
@Id
String ssn;
+
+ public Person() {
+ }
+
+ public Person(String ssn) {
+ this.ssn = ssn;
+ }
}
\ No newline at end of file
Modified: core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java 2010-02-10 17:34:16 UTC (rev 18766)
+++ core/trunk/core/src/main/java/org/hibernate/event/def/DefaultPersistEventListener.java 2010-02-10 17:38:59 UTC (rev 18767)
@@ -1,10 +1,10 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
- * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
+ * Copyright (c) 2010, Red Hat Inc. 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.
+ * distributed under license by Red Hat Inc.
*
* 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
@@ -20,7 +20,6 @@
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
- *
*/
package org.hibernate.event.def;
@@ -32,10 +31,12 @@
import org.hibernate.ObjectDeletedException;
import org.hibernate.PersistentObjectException;
import org.hibernate.engine.CascadingAction;
+import org.hibernate.engine.EntityEntry;
import org.hibernate.event.EventSource;
import org.hibernate.event.PersistEvent;
import org.hibernate.event.PersistEventListener;
import org.hibernate.engine.SessionImplementor;
+import org.hibernate.id.ForeignGenerator;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
@@ -48,7 +49,6 @@
* @author Gavin King
*/
public class DefaultPersistEventListener extends AbstractSaveEventListener implements PersistEventListener {
-
private static final Logger log = LoggerFactory.getLogger(DefaultPersistEventListener.class);
/**
@@ -69,19 +69,18 @@
* @throws HibernateException
*/
public void onPersist(PersistEvent event, Map createCache) throws HibernateException {
-
final SessionImplementor source = event.getSession();
final Object object = event.getObject();
final Object entity;
- if (object instanceof HibernateProxy) {
+ if ( object instanceof HibernateProxy ) {
LazyInitializer li = ( (HibernateProxy) object ).getHibernateLazyInitializer();
if ( li.isUninitialized() ) {
- if ( li.getSession()==source ) {
+ if ( li.getSession() == source ) {
return; //NOTE EARLY EXIT!
}
else {
- throw new PersistentObjectException("uninitialized proxy passed to persist()");
+ throw new PersistentObjectException( "uninitialized proxy passed to persist()" );
}
}
entity = li.getImplementation();
@@ -89,32 +88,58 @@
else {
entity = object;
}
-
- int entityState = getEntityState(
- entity,
- event.getEntityName(),
- source.getPersistenceContext().getEntry(entity),
- source
- );
-
- switch (entityState) {
- case DETACHED:
- throw new PersistentObjectException(
- "detached entity passed to persist: " +
- getLoggableName( event.getEntityName(), entity )
- );
+
+ final String entityName;
+ if ( event.getEntityName() != null ) {
+ entityName = event.getEntityName();
+ }
+ else {
+ entityName = source.bestGuessEntityName( entity );
+ event.setEntityName( entityName );
+ }
+
+ final EntityEntry entityEntry = source.getPersistenceContext().getEntry( entity );
+ int entityState = getEntityState( entity, entityName, entityEntry, source );
+ if ( entityState == DETACHED ) {
+ // JPA 2, in its version of a "foreign generated", allows the id attribute value
+ // to be manually set by the user, even though this manual value is irrelevant.
+ // The issue is that this causes problems with the Hibernate unsaved-value strategy
+ // which comes into play here in determining detached/transient state.
+ //
+ // Detect if we have this situation and if so null out the id value and calculate the
+ // entity state again.
+
+ // NOTE: entityEntry must be null to get here, so we cannot use any of its values
+ EntityPersister persister = source.getFactory().getEntityPersister( entityName );
+ if ( ForeignGenerator.class.isInstance( persister.getIdentifierGenerator() ) ) {
+ if ( log.isDebugEnabled() ) {
+ if ( persister.getIdentifier( entity, source ) != null ) {
+ log.debug( "Resetting entity id attribute to null for foreign generator" );
+ }
+ }
+ persister.setIdentifier( entity, null, source );
+ entityState = getEntityState( entity, entityName, entityEntry, source );
+ }
+ }
+
+ switch ( entityState ) {
+ case DETACHED:
+ throw new PersistentObjectException(
+ "detached entity passed to persist: " +
+ getLoggableName( event.getEntityName(), entity )
+ );
case PERSISTENT:
- entityIsPersistent(event, createCache);
+ entityIsPersistent( event, createCache );
break;
case TRANSIENT:
- entityIsTransient(event, createCache);
+ entityIsTransient( event, createCache );
break;
- default:
- throw new ObjectDeletedException(
- "deleted entity passed to persist",
- null,
+ default:
+ throw new ObjectDeletedException(
+ "deleted entity passed to persist",
+ null,
getLoggableName( event.getEntityName(), entity )
- );
+ );
}
}
More information about the hibernate-commits
mailing list