[hibernate-commits] Hibernate SVN: r18686 - 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 3 01:58:47 EST 2010


Author: steve.ebersole at jboss.com
Date: 2010-02-03 01:58:46 -0500 (Wed, 03 Feb 2010)
New Revision: 18686

Modified:
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/DerivedIdentitySimpleParentSimpleDepTest.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/FinancialHistory.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/MedicalHistory.java
   core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Person.java
   core/trunk/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java
Log:
HHH-4861 - Allow lookup by the "simple" pk type of "parent entity" in "derived identities" cases


Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/DerivedIdentitySimpleParentSimpleDepTest.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/DerivedIdentitySimpleParentSimpleDepTest.java	2010-02-03 06:51:48 UTC (rev 18685)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/DerivedIdentitySimpleParentSimpleDepTest.java	2010-02-03 06:58:46 UTC (rev 18686)
@@ -14,56 +14,80 @@
 	public void testOneToOneExplicitJoinColumn() throws Exception {
 		assertTrue( SchemaUtil.isColumnPresent( "MedicalHistory", "FK", getCfg() ) );
 		assertTrue( ! SchemaUtil.isColumnPresent( "MedicalHistory", "id", getCfg() ) );
-		Person e = new Person();
-		e.ssn = "aaa";
-		Session s = openSession(  );
+
+		Session s = openSession();
 		s.getTransaction().begin();
-		s.persist( e );
-		MedicalHistory d = new MedicalHistory();
-		d.patient = e;
-		s.persist( d );
-		s.flush();
-		s.clear();
-		final Class<MedicalHistory> clazz = MedicalHistory.class;
-		d = getDerivedClassById( e, s, clazz );
-		assertEquals( e.ssn, d.patient.ssn );
-		d.lastupdate = new Date();
-		s.flush();
-		s.clear();
-		d = getDerivedClassById( e, s, clazz );
-		assertNotNull( d.lastupdate );
-		s.getTransaction().rollback();
+		Person person = new Person( "aaa" );
+		s.persist( person );
+		MedicalHistory medicalHistory = new MedicalHistory( person );
+		s.persist( medicalHistory );
+		s.getTransaction().commit();
 		s.close();
-	}
 
-	private <T> T getDerivedClassById(Person e, Session s, Class<T> clazz) {
-		return ( T )
-				s.createQuery( "from " + clazz.getName() + " mh where mh.patient.ssn = :ssn")
-					.setParameter( "ssn", e.ssn ).uniqueResult();
+		s = openSession();
+		s.getTransaction().begin();
+		medicalHistory = (MedicalHistory) s.get( MedicalHistory.class, "aaa" );
+		assertEquals( person.ssn, medicalHistory.patient.ssn );
+		medicalHistory.lastupdate = new Date();
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.getTransaction().begin();
+		medicalHistory = (MedicalHistory) s.get( MedicalHistory.class, "aaa" );
+		assertNotNull( medicalHistory.lastupdate );
+		s.delete( medicalHistory );
+		s.getTransaction().commit();
+		s.close();
 	}
 
 	public void testManyToOneExplicitJoinColumn() throws Exception {
 		assertTrue( SchemaUtil.isColumnPresent( "FinancialHistory", "patient_ssn", getCfg() ) );
 		assertTrue( ! SchemaUtil.isColumnPresent( "FinancialHistory", "id", getCfg() ) );
-		Person e = new Person();
-		e.ssn = "aaa";
-		Session s = openSession(  );
+
+		Session s = openSession();
 		s.getTransaction().begin();
+		Person person = new Person( "aaa" );
+		s.persist( person );
+		FinancialHistory financialHistory = new FinancialHistory( person );
+		s.persist( financialHistory );
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.getTransaction().begin();
+		financialHistory = (FinancialHistory) s.get( FinancialHistory.class, "aaa" );
+		assertEquals( person.ssn, financialHistory.patient.ssn );
+		financialHistory.lastUpdate = new Date();
+		s.getTransaction().commit();
+		s.close();
+
+		s = openSession();
+		s.getTransaction().begin();
+		financialHistory = (FinancialHistory) s.get( FinancialHistory.class, "aaa" );
+		assertNotNull( financialHistory.lastUpdate );
+		s.delete( financialHistory );
+		s.getTransaction().commit();
+		s.close();
+	}
+
+	public void testSimplePkValueLoading() {
+		Session s = openSession();
+		s.getTransaction().begin();
+		Person e = new Person( "aaa" );
 		s.persist( e );
-		FinancialHistory d = new FinancialHistory();
-		d.patient = e;
+		FinancialHistory d = new FinancialHistory( e );
 		s.persist( d );
-		s.flush();
-		s.clear();
-		d = getDerivedClassById(e, s, FinancialHistory.class);
-		assertEquals( e.ssn, d.patient.ssn );
-		d.lastupdate = new Date();
-		s.flush();
-		s.clear();
-		d = getDerivedClassById(e, s, FinancialHistory.class);
-		assertNotNull( d.lastupdate );
-		s.getTransaction().rollback();
+		s.getTransaction().commit();
 		s.close();
+
+		s = openSession();
+		s.getTransaction().begin();
+		FinancialHistory history = (FinancialHistory) s.get( FinancialHistory.class, "aaa" );
+		assertNotNull( history );
+		s.delete( history );
+		s.getTransaction().commit();
+		s.close();
 	}
 
 	@Override

Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/FinancialHistory.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/FinancialHistory.java	2010-02-03 06:51:48 UTC (rev 18685)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/FinancialHistory.java	2010-02-03 06:58:46 UTC (rev 18686)
@@ -16,13 +16,18 @@
  */
 @Entity
 public class FinancialHistory implements Serializable {
-	
-	@Temporal(TemporalType.DATE)
-	Date lastupdate;
-
 	@Id
 	//@JoinColumn(name = "FK")
 	@ManyToOne
 	Person patient;
 
+	@Temporal(TemporalType.DATE)
+	Date lastUpdate;
+
+	public FinancialHistory() {
+	}
+
+	public FinancialHistory(Person patient) {
+		this.patient = patient;
+	}
 }
\ No newline at end of file

Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/MedicalHistory.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/MedicalHistory.java	2010-02-03 06:51:48 UTC (rev 18685)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/MedicalHistory.java	2010-02-03 06:58:46 UTC (rev 18686)
@@ -16,12 +16,18 @@
  */
 @Entity
 public class MedicalHistory implements Serializable {
+	@Id
+	@JoinColumn(name = "FK")
+	@OneToOne
+	Person patient;
 
 	@Temporal(TemporalType.DATE)
 	Date lastupdate;
 
-	@Id
-	@JoinColumn(name = "FK")
-	@OneToOne
-	Person patient;
+	public MedicalHistory() {
+	}
+
+	public MedicalHistory(Person patient) {
+		this.patient = patient;
+	}
 }
\ No newline at end of file

Modified: core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Person.java
===================================================================
--- core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Person.java	2010-02-03 06:51:48 UTC (rev 18685)
+++ core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Person.java	2010-02-03 06:58:46 UTC (rev 18686)
@@ -11,4 +11,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/DefaultLoadEventListener.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java	2010-02-03 06:51:48 UTC (rev 18685)
+++ core/trunk/core/src/main/java/org/hibernate/event/def/DefaultLoadEventListener.java	2010-02-03 06:58:46 UTC (rev 18686)
@@ -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;
 
@@ -54,6 +53,8 @@
 import org.hibernate.pretty.MessageHelper;
 import org.hibernate.proxy.HibernateProxy;
 import org.hibernate.proxy.LazyInitializer;
+import org.hibernate.type.EmbeddedComponentType;
+import org.hibernate.type.EntityType;
 import org.hibernate.type.Type;
 import org.hibernate.type.TypeFactory;
 
@@ -106,6 +107,31 @@
 		else {
 			Class idClass = persister.getIdentifierType().getReturnedClass();
 			if ( idClass != null && ! idClass.isInstance( event.getEntityId() ) ) {
+				// we may have the kooky jpa requirement of allowing find-by-id where
+				// "id" is the "simple pk value" of a dependent objects parent.  This
+				// is part of its generally goofy "derived identity" "feature"
+				if ( persister.getEntityMetamodel().getIdentifierProperty().isEmbedded() ) {
+					final EmbeddedComponentType dependentIdType =
+							(EmbeddedComponentType) persister.getEntityMetamodel().getIdentifierProperty().getType();
+					if ( dependentIdType.getSubtypes().length == 1 ) {
+						final Type singleSubType = dependentIdType.getSubtypes()[0];
+						if ( singleSubType.isEntityType() ) {
+							final EntityType dependentParentType = (EntityType) singleSubType;
+							final Type dependentParentIdType = dependentParentType.getIdentifierOrUniqueKeyType( source.getFactory() );
+							if ( dependentParentIdType.getReturnedClass().isInstance( event.getEntityId() ) ) {
+								// yep that's what we have...
+								loadByDerivedIdentitySimplePkValue(
+										event,
+										loadType,
+										persister,
+										dependentIdType,
+										source.getFactory().getEntityPersister( dependentParentType.getAssociatedEntityName() )
+								);
+								return;
+							}
+						}
+					}
+				}
 				throw new TypeMismatchException(
 						"Provided id of the wrong type for class " + persister.getEntityName() + ". Expected: " + idClass + ", got " + event.getEntityId().getClass()
 				);
@@ -136,6 +162,42 @@
 		}
 	}
 
+	private void loadByDerivedIdentitySimplePkValue(
+			LoadEvent event,
+			LoadEventListener.LoadType options,
+			EntityPersister dependentPersister,
+			EmbeddedComponentType dependentIdType,
+			EntityPersister parentPersister) {
+		final EntityKey parentEntityKey = new EntityKey(
+				event.getEntityId(),
+				parentPersister,
+				event.getSession().getEntityMode()
+		);
+		final Object parent = doLoad(
+				event,
+				parentPersister,
+				parentEntityKey,
+				options
+		);
+
+		Serializable dependent = (Serializable) dependentIdType.instantiate( parent, event.getSession() );
+		dependentIdType.setPropertyValues( dependent, new Object[] {parent}, event.getSession().getEntityMode() );
+		final EntityKey dependentEntityKey = new EntityKey(
+				dependent,
+				dependentPersister,
+				event.getSession().getEntityMode()
+		);
+		event.setEntityId( dependent );
+		dependent = (Serializable) doLoad(
+				event,
+				dependentPersister,
+				dependentEntityKey,
+				options
+		);
+
+		event.setResult( dependent );
+	}
+
 	/**
 	 * Perfoms the load of an entity.
 	 *



More information about the hibernate-commits mailing list