HHH-4529 Add support for id copy when @MapsId is used.
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18633 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
fc20582ede
commit
7c72886f6e
|
@ -967,127 +967,6 @@ public final class
|
|||
return true;
|
||||
}
|
||||
|
||||
// /*
|
||||
// * Get the annotated elements, guessing the access type from @Id or @EmbeddedId presence.
|
||||
// * Change EntityBinder by side effect
|
||||
// */
|
||||
// private static InheritanceState.ElementsToProcess getElementsToProcess(
|
||||
// PersistentClass persistentClass, XClass clazzToProcess,
|
||||
// Map<XClass, InheritanceState> inheritanceStatePerClass,
|
||||
// EntityBinder entityBinder, ExtendedMappings mappings
|
||||
// ) {
|
||||
// InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess );
|
||||
// assert !inheritanceState.isEmbeddableSuperclass();
|
||||
//
|
||||
//
|
||||
// List<XClass> classesToProcess = getMappedSuperclassesTillNextEntityOrdered(
|
||||
// persistentClass, clazzToProcess, inheritanceStatePerClass, mappings
|
||||
// );
|
||||
//
|
||||
// AccessType accessType = determineDefaultAccessType( clazzToProcess, inheritanceStatePerClass );
|
||||
//
|
||||
// List<PropertyData> elements = new ArrayList<PropertyData>();
|
||||
// int deep = classesToProcess.size();
|
||||
// int idPropertyCount = 0;
|
||||
//
|
||||
// for ( int index = 0; index < deep; index++ ) {
|
||||
// PropertyContainer propertyContainer = new PropertyContainer( classesToProcess.get( index ), clazzToProcess );
|
||||
// int currentIdPropertyCount = addElementsOfClass( elements, accessType, propertyContainer, mappings );
|
||||
// idPropertyCount += currentIdPropertyCount;
|
||||
// }
|
||||
//
|
||||
// entityBinder.setPropertyAccessType( accessType );
|
||||
//
|
||||
// if ( idPropertyCount == 0 && !inheritanceState.hasParents() ) {
|
||||
// throw new AnnotationException( "No identifier specified for entity: " + clazzToProcess.getName() );
|
||||
// }
|
||||
//
|
||||
// return new InheritanceState.ElementsToProcess( elements, idPropertyCount);
|
||||
// }
|
||||
|
||||
// private static AccessType determineDefaultAccessType(XClass annotatedClass, Map<XClass, InheritanceState> inheritanceStatePerClass) {
|
||||
// XClass xclass = annotatedClass;
|
||||
// while ( xclass != null && !Object.class.getName().equals( xclass.getName() ) ) {
|
||||
// if ( xclass.isAnnotationPresent( Entity.class ) || xclass.isAnnotationPresent( MappedSuperclass.class ) ) {
|
||||
// for ( XProperty prop : xclass.getDeclaredProperties( AccessType.PROPERTY.getType() ) ) {
|
||||
// if ( prop.isAnnotationPresent( Id.class ) || prop.isAnnotationPresent( EmbeddedId.class ) ) {
|
||||
// return AccessType.PROPERTY;
|
||||
// }
|
||||
// }
|
||||
// for ( XProperty prop : xclass.getDeclaredProperties( AccessType.FIELD.getType() ) ) {
|
||||
// if ( prop.isAnnotationPresent( Id.class ) || prop.isAnnotationPresent( EmbeddedId.class ) ) {
|
||||
// return AccessType.FIELD;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// xclass = xclass.getSuperclass();
|
||||
// }
|
||||
// throw new AnnotationException( "No identifier specified for entity: " + annotatedClass.getName() );
|
||||
// }
|
||||
//
|
||||
// private static List<XClass> getMappedSuperclassesTillNextEntityOrdered(
|
||||
// PersistentClass persistentClass, XClass annotatedClass,
|
||||
// Map<XClass, InheritanceState> inheritanceStatePerClass,
|
||||
// ExtendedMappings mappings
|
||||
// ) {
|
||||
//
|
||||
// //ordered to allow proper messages on properties subclassing
|
||||
// List<XClass> classesToProcess = new ArrayList<XClass>();
|
||||
// XClass currentClassInHierarchy = annotatedClass;
|
||||
// InheritanceState superclassState;
|
||||
// final ReflectionManager reflectionManager = mappings.getReflectionManager();
|
||||
// do {
|
||||
// classesToProcess.add( 0, currentClassInHierarchy );
|
||||
// XClass superClass = currentClassInHierarchy;
|
||||
// do {
|
||||
// superClass = superClass.getSuperclass();
|
||||
// superclassState = inheritanceStatePerClass.get( superClass );
|
||||
// }
|
||||
// while ( superClass != null && !reflectionManager
|
||||
// .equals( superClass, Object.class ) && superclassState == null );
|
||||
//
|
||||
// currentClassInHierarchy = superClass;
|
||||
// }
|
||||
// while ( superclassState != null && superclassState.isEmbeddableSuperclass() );
|
||||
// addMappedSuperClassInMetadata(
|
||||
// persistentClass, annotatedClass, inheritanceStatePerClass, mappings, classesToProcess
|
||||
// );
|
||||
//
|
||||
//
|
||||
// return classesToProcess;
|
||||
// }
|
||||
//
|
||||
// private static void addMappedSuperClassInMetadata(PersistentClass persistentClass,
|
||||
// XClass annotatedClass,
|
||||
// Map<XClass, InheritanceState> inheritanceStatePerClass,
|
||||
// ExtendedMappings mappings,
|
||||
// List<XClass> classesToProcess) {
|
||||
// //add @MappedSuperclass in the metadata
|
||||
// // classes from 0 to n-1 are @MappedSuperclass and should be linked
|
||||
// org.hibernate.mapping.MappedSuperclass mappedSuperclass = null;
|
||||
// final InheritanceState superEntityState =
|
||||
// InheritanceState.getInheritanceStateOfSuperEntity( annotatedClass, inheritanceStatePerClass );
|
||||
// PersistentClass superEntity =
|
||||
// superEntityState != null ?
|
||||
// mappings.getClass( superEntityState.getClazz().getName() ) :
|
||||
// null;
|
||||
// final int lastMappedSuperclass = classesToProcess.size() - 1;
|
||||
// for ( int index = 0 ; index < lastMappedSuperclass ; index++ ) {
|
||||
// org.hibernate.mapping.MappedSuperclass parentSuperclass = mappedSuperclass;
|
||||
// final Class<?> type = mappings.getReflectionManager().toClass( classesToProcess.get( index ) );
|
||||
// //add MAppedSuperclass if not already there
|
||||
// mappedSuperclass = mappings.getMappedSuperclass( type );
|
||||
// if (mappedSuperclass == null) {
|
||||
// mappedSuperclass = new org.hibernate.mapping.MappedSuperclass(parentSuperclass, superEntity );
|
||||
// mappedSuperclass.setMappedClass( type );
|
||||
// mappings.addMappedSuperclass( type, mappedSuperclass );
|
||||
// }
|
||||
// }
|
||||
// if (mappedSuperclass != null) {
|
||||
// persistentClass.setSuperMappedSuperclass(mappedSuperclass);
|
||||
// }
|
||||
// }
|
||||
|
||||
/*
|
||||
* Process the filters defined on the given class, as well as all filters defined
|
||||
* on the MappedSuperclass(s) in the inheritance hierarchy
|
||||
|
@ -1347,11 +1226,6 @@ public final class
|
|||
}
|
||||
log.trace( "{} is a version property", inferredData.getPropertyName() );
|
||||
RootClass rootClass = (RootClass) propertyHolder.getPersistentClass();
|
||||
// PropertyBinder propBinder = new PropertyBinder();
|
||||
// propBinder.setName( inferredData.getPropertyName() );
|
||||
// propBinder.setReturnedClassName( inferredData.getTypeName() );
|
||||
// propBinder.setLazy( false );
|
||||
// propBinder.setAccessType( inferredData.getDefaultAccess() );
|
||||
propertyBinder.setColumns( columns );
|
||||
Property prop = propertyBinder.makePropertyValueAndBind();
|
||||
propertyBinder.getSimpleValueBinder().setVersion(true);
|
||||
|
@ -1809,23 +1683,43 @@ public final class
|
|||
|
||||
propertyBinder.setLazy( lazy );
|
||||
propertyBinder.setColumns( columns );
|
||||
// if ( isIdentifierMapper ) {
|
||||
// propertyBinder.setInsertable( false );
|
||||
// propertyBinder.setUpdatable( false );
|
||||
// }
|
||||
|
||||
propertyBinder.makePropertyValueAndBind();
|
||||
|
||||
}
|
||||
if (isOverridden) {
|
||||
final PropertyData mapsIdProperty = BinderHelper.getPropertyAnnotatedWithMapsId(
|
||||
isId, propertyHolder, property.getName(), mappings
|
||||
);
|
||||
HashMap<String, IdGenerator> localGenerators = (HashMap<String, IdGenerator>) classGenerators.clone();
|
||||
final IdGenerator foreignGenerator = new IdGenerator();
|
||||
foreignGenerator.setIdentifierGeneratorStrategy( "assigned" );
|
||||
foreignGenerator.setName( "Hibernate-local--foreign generator" );
|
||||
foreignGenerator.setIdentifierGeneratorStrategy( "foreign" );
|
||||
foreignGenerator.addParam( "property", mapsIdProperty.getPropertyName() );
|
||||
localGenerators.put( foreignGenerator.getName(), foreignGenerator );
|
||||
|
||||
BinderHelper.makeIdGenerator(
|
||||
(SimpleValue) propertyBinder.getValue(),
|
||||
foreignGenerator.getIdentifierGeneratorStrategy(),
|
||||
foreignGenerator.getName(),
|
||||
mappings,
|
||||
localGenerators
|
||||
);
|
||||
}
|
||||
if (isId) {
|
||||
//components and regular basic types create SimpleValue objects
|
||||
final SimpleValue value = ( SimpleValue ) propertyBinder.getValue();
|
||||
processId(
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
value,
|
||||
classGenerators,
|
||||
isIdentifierMapper,
|
||||
mappings
|
||||
);
|
||||
if ( !isOverridden ) {
|
||||
processId(
|
||||
propertyHolder,
|
||||
inferredData,
|
||||
value,
|
||||
classGenerators,
|
||||
isIdentifierMapper,
|
||||
mappings
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
//init index
|
||||
|
@ -1862,7 +1756,13 @@ public final class
|
|||
}
|
||||
}
|
||||
|
||||
private static void processId(PropertyHolder propertyHolder, PropertyData inferredData, SimpleValue idValue, HashMap<String, IdGenerator> classGenerators, boolean isIdentifierMapper, ExtendedMappings mappings) {
|
||||
private static void processId(
|
||||
PropertyHolder propertyHolder,
|
||||
PropertyData inferredData,
|
||||
SimpleValue idValue,
|
||||
HashMap<String, IdGenerator> classGenerators,
|
||||
boolean isIdentifierMapper,
|
||||
ExtendedMappings mappings) {
|
||||
if ( isIdentifierMapper ) {
|
||||
throw new AnnotationException(
|
||||
"@IdClass class should not have @Id nor @EmbeddedId properties: "
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e1.a;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.IdClass;
|
||||
import javax.persistence.ManyToOne;
|
||||
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
@IdClass(DependentId.class)
|
||||
public class Dependent {
|
||||
@Id
|
||||
String name;
|
||||
|
||||
// id attribute mapped by join column default
|
||||
@Id
|
||||
@ManyToOne
|
||||
Employee emp;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e1.a;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class DependentId implements Serializable {
|
||||
String name;
|
||||
long empPK; // corresponds to PK type of Employee
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e1.a;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.test.annotations.TestCase;
|
||||
import org.hibernate.test.util.SchemaUtil;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class
|
||||
DerivedIdentitySimpleParentIdClassDepTest extends TestCase {
|
||||
|
||||
public void testManyToOne() throws Exception {
|
||||
// assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK", getCfg() ) );
|
||||
// assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "empPK", getCfg() ) );
|
||||
// Employee e = new Employee();
|
||||
// e.empId = 1;
|
||||
// e.empName = "Emmanuel";
|
||||
// Session s = openSession( );
|
||||
// s.getTransaction().begin();
|
||||
// s.persist( e );
|
||||
// Dependent d = new Dependent();
|
||||
// d.emp = e;
|
||||
// d.name = "Doggy";
|
||||
// d.emp = e;
|
||||
// s.persist( d );
|
||||
// s.flush();
|
||||
// s.clear();
|
||||
// DependentId dId = new DependentId();
|
||||
// dId.name = d.name;
|
||||
// dId.empPK = d.emp.empId;
|
||||
// d = (Dependent) s.get( Dependent.class, dId );
|
||||
// assertEquals( e.empId, d.emp.empId );
|
||||
// s.getTransaction().rollback();
|
||||
// s.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?>[] getAnnotatedClasses() {
|
||||
return new Class<?>[] {
|
||||
//Dependent.class,
|
||||
//Employee.class
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.hibernate.test.annotations.derivedidentities.e1.a;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class Employee {
|
||||
@Id
|
||||
long empId;
|
||||
String empName;
|
||||
}
|
|
@ -23,7 +23,7 @@ public class
|
|||
d.emp = e;
|
||||
d.id = new DependentId();
|
||||
d.id.name = "Doggy";
|
||||
d.id.empPK = e.empId; //FIXME not needed when foreign is enabled
|
||||
//d.id.empPK = e.empId; //FIXME not needed when foreign is enabled
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
@ -46,7 +46,7 @@ public class
|
|||
d.emp = e;
|
||||
d.id = new DependentId();
|
||||
d.id.name = "Doggy";
|
||||
d.id.empPK = e.empId; //FIXME not needed when foreign is enabled
|
||||
//d.id.empPK = e.empId; //FIXME not needed when foreign is enabled
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
|
|
@ -25,9 +25,9 @@ public class DerivedIdentityIdClassParentEmbeddedIdDepTest extends TestCase {
|
|||
d.emp = e;
|
||||
d.id = new DependentId();
|
||||
d.id.name = "Doggy";
|
||||
d.id.empPK = new EmployeeId();
|
||||
d.id.empPK.firstName = e.firstName; //FIXME not needed when foreign is enabled
|
||||
d.id.empPK.lastName = e.lastName; //FIXME not needed when foreign is enabled
|
||||
// d.id.empPK = new EmployeeId(); //FIXME not needed when foreign is enabled
|
||||
// d.id.empPK.firstName = e.firstName; //FIXME not needed when foreign is enabled
|
||||
// d.id.empPK.lastName = e.lastName; //FIXME not needed when foreign is enabled
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
|
|
@ -25,9 +25,9 @@ public class DerivedIdentityEmbeddedIdParentEmbeddedIdDepTest extends TestCase {
|
|||
d.emp = e;
|
||||
d.id = new DependentId();
|
||||
d.id.name = "Doggy";
|
||||
d.id.empPK = new EmployeeId();
|
||||
d.id.empPK.firstName = e.empId.firstName; //FIXME not needed when foreign is enabled
|
||||
d.id.empPK.lastName = e.empId.lastName; //FIXME not needed when foreign is enabled
|
||||
// d.id.empPK = new EmployeeId();
|
||||
// d.id.empPK.firstName = e.empId.firstName; //FIXME not needed when foreign is enabled
|
||||
// d.id.empPK.lastName = e.empId.lastName; //FIXME not needed when foreign is enabled
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
|
|
@ -21,7 +21,7 @@ public class DerivedIdentitySimpleParentSimpleDepMapsIdTest extends TestCase {
|
|||
s.persist( e );
|
||||
MedicalHistory d = new MedicalHistory();
|
||||
d.patient = e;
|
||||
d.id = "aaa"; //FIXME not needed when foreign is enabled
|
||||
//d.id = "aaa"; //FIXME not needed when foreign is enabled
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
@ -46,7 +46,7 @@ public class DerivedIdentitySimpleParentSimpleDepMapsIdTest extends TestCase {
|
|||
s.persist( e );
|
||||
FinancialHistory d = new FinancialHistory();
|
||||
d.patient = e;
|
||||
d.id = "aaa"; //FIXME not needed when foreign is enabled
|
||||
//d.id = "aaa"; //FIXME not needed when foreign is enabled
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
s.clear();
|
||||
|
|
|
@ -22,9 +22,9 @@ public class DerivedIdentityIdClassParentSameIdTypeDepTest extends TestCase {
|
|||
s.getTransaction().begin();
|
||||
s.persist( e );
|
||||
MedicalHistory d = new MedicalHistory();
|
||||
d.id = new PersonId();
|
||||
d.id.firstName = "Emmanuel"; //FIXME not needed when foreign is enabled
|
||||
d.id.lastName = "Bernard"; //FIXME not needed when foreign is enabled
|
||||
// d.id = new PersonId(); //FIXME not needed when foreign is enabled
|
||||
// d.id.firstName = "Emmanuel"; //FIXME not needed when foreign is enabled
|
||||
// d.id.lastName = "Bernard"; //FIXME not needed when foreign is enabled
|
||||
d.patient = e;
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
|
|
|
@ -21,9 +21,9 @@ public class DerivedIdentityEmbeddedIdParentSameIdTypeDepTest extends TestCase {
|
|||
s.getTransaction().begin();
|
||||
s.persist( e );
|
||||
MedicalHistory d = new MedicalHistory();
|
||||
d.id = new PersonId();
|
||||
d.id.firstName = "Emmanuel"; //FIXME not needed when foreign is enabled
|
||||
d.id.lastName = "Bernard"; //FIXME not needed when foreign is enabled
|
||||
// d.id = new PersonId();
|
||||
// d.id.firstName = "Emmanuel"; //FIXME not needed when foreign is enabled
|
||||
// d.id.lastName = "Bernard"; //FIXME not needed when foreign is enabled
|
||||
d.patient = e;
|
||||
s.persist( d );
|
||||
s.flush();
|
||||
|
|
Loading…
Reference in New Issue