Author: epbernard
Date: 2010-01-25 12:19:05 -0500 (Mon, 25 Jan 2010)
New Revision: 18619
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/Dependent.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/DerivedIdentitySimpleParentEmbeddedDepTest.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/Employee.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/
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/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Simple.java
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java
Log:
HHH-4529 support for derived entity id as a XToOne pointing to the master entity
HHH-4840 support for Core style embedded id (after all these years :) )
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2010-01-25
16:23:59 UTC (rev 18618)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -625,10 +625,10 @@
HashMap<String, IdGenerator> classGenerators = buildLocalGenerators(
clazzToProcess, mappings );
// check properties
- List<PropertyData> elements =
- getElementsToProcess(
- persistentClass, clazzToProcess, inheritanceStatePerClass, entityBinder, mappings
- );
+ final ElementsToProcess elementsToProcess = getElementsToProcess(
+ persistentClass, clazzToProcess, inheritanceStatePerClass, entityBinder, mappings
+ );
+
final boolean subclassAndSingleTableStrategy = inheritanceState.getType() ==
InheritanceType.SINGLE_TABLE
&& inheritanceState.hasParents();
//process idclass if any
@@ -674,7 +674,9 @@
isComponent,
propertyAccessor, entityBinder,
true,
- false, mappings, inheritanceStatePerClass
+ false,
+ mappings,
+ inheritanceStatePerClass
);
inferredData = new PropertyPreloadedData(
propertyAccessor, "_identifierMapper", compositeClass
@@ -683,9 +685,11 @@
propertyHolder,
inferredData,
baseInferredData,
- propertyAccessor, false,
+ propertyAccessor,
+ false,
entityBinder,
- true, true,
+ true,
+ true,
false, mappings, inheritanceStatePerClass
);
entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
@@ -720,8 +724,11 @@
idProperties.add( ( (Property) properties.next() ).getName() );
}
}
+ else {
+ entityBinder.setWrapIdsInEmbeddedComponents( elementsToProcess.getIdPropertyCount()
> 1 );
+ }
Set<String> missingIdProperties = new HashSet<String>( idProperties );
- for (PropertyData propertyAnnotatedElement : elements) {
+ for (PropertyData propertyAnnotatedElement : elementsToProcess.getElements() ) {
String propertyName = propertyAnnotatedElement.getPropertyName();
if ( !idProperties.contains( propertyName ) ) {
processElementAnnotations(
@@ -979,7 +986,7 @@
* Get the annotated elements, guessing the access type from @Id or @EmbeddedId
presence.
* Change EntityBinder by side effect
*/
- private static List<PropertyData> getElementsToProcess(
+ private static ElementsToProcess getElementsToProcess(
PersistentClass persistentClass, XClass clazzToProcess,
Map<XClass, InheritanceState> inheritanceStatePerClass,
EntityBinder entityBinder, ExtendedMappings mappings
@@ -996,23 +1003,41 @@
List<PropertyData> elements = new ArrayList<PropertyData>();
int deep = classesToProcess.size();
- boolean hasIdentifier = false;
+ int idPropertyCount = 0;
for ( int index = 0; index < deep; index++ ) {
- PropertyContainer properyContainer = new PropertyContainer( classesToProcess.get(
index ), clazzToProcess );
- boolean currentHasIdentifier = addElementsOfClass( elements, accessType,
properyContainer, mappings );
- hasIdentifier = hasIdentifier || currentHasIdentifier;
+ PropertyContainer propertyContainer = new PropertyContainer( classesToProcess.get(
index ), clazzToProcess );
+ int currentIdPropertyCount = addElementsOfClass( elements, accessType,
propertyContainer, mappings );
+ idPropertyCount += currentIdPropertyCount;
}
entityBinder.setPropertyAccessType( accessType );
- if ( !hasIdentifier && !inheritanceState.hasParents() ) {
+ if ( idPropertyCount == 0 && !inheritanceState.hasParents() ) {
throw new AnnotationException( "No identifier specified for entity: " +
clazzToProcess.getName() );
}
- return elements;
+ return new ElementsToProcess( elements, idPropertyCount);
}
+ private static final class ElementsToProcess {
+ private final List<PropertyData> properties;
+ private final int idPropertyCount;
+
+ public List<PropertyData> getElements() {
+ return properties;
+ }
+
+ public int getIdPropertyCount() {
+ return idPropertyCount;
+ }
+
+ private ElementsToProcess(List<PropertyData> properties, int idPropertyCount) {
+ this.properties = properties;
+ this.idPropertyCount = idPropertyCount;
+ }
+ }
+
private static AccessType determineDefaultAccessType(XClass annotatedClass,
Map<XClass, InheritanceState> inheritanceStatePerClass) {
XClass xclass = annotatedClass;
while ( xclass != null && !Object.class.getName().equals( xclass.getName() ) )
{
@@ -1207,13 +1232,13 @@
* strategy is used
* @param propertyContainer Metadata about a class and its properties
* @param mappings Mapping meta data
- * @return {@code true} in case an id property was found while iterating the elements of
{@code annoatedClass} using
+ * @return the number of id properties found while iterating the elements of {@code
annoatedClass} using
* the determined access strategy, {@code false} otherwise.
*/
- private static boolean addElementsOfClass(
+ private static int addElementsOfClass(
List<PropertyData> elements, AccessType defaultAccessType, PropertyContainer
propertyContainer, ExtendedMappings mappings
) {
- boolean hasIdentifier = false;
+ int idPropertyCounter = 0;
AccessType accessType = defaultAccessType;
if ( propertyContainer.hasExplicitAccessStrategy() ) {
@@ -1223,21 +1248,21 @@
propertyContainer.assertTypesAreResolvable( accessType );
Collection<XProperty> properties = propertyContainer.getProperties( accessType
);
for ( XProperty p : properties ) {
- final boolean currentHasIdentifier = addProperty(
+ final int currentIdPropertyCounter = addProperty(
propertyContainer, p, elements, accessType.getType(), mappings
);
- hasIdentifier = hasIdentifier || currentHasIdentifier;
+ idPropertyCounter += currentIdPropertyCounter;
}
- return hasIdentifier;
+ return idPropertyCounter;
}
- private static boolean addProperty(
+ private static int addProperty(
PropertyContainer propertyContainer, XProperty property, List<PropertyData>
annElts,
String propertyAccessor, ExtendedMappings mappings
) {
final XClass declaringClass = propertyContainer.getDeclaringClass();
final XClass entity = propertyContainer.getEntityAtStake();
- boolean hasIdentifier;
+ int idPropertyCounter = 0;
PropertyData propertyAnnotatedElement = new PropertyInferredData(
declaringClass, property, propertyAccessor,
mappings.getReflectionManager() );
@@ -1249,17 +1274,16 @@
final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent(
EmbeddedId.class ) ) {
annElts.add( 0, propertyAnnotatedElement );
- hasIdentifier = true;
+ idPropertyCounter++;
}
else {
annElts.add( propertyAnnotatedElement );
- hasIdentifier = false;
}
if ( element.isAnnotationPresent( MapsId.class ) ) {
mappings.addPropertyAnnotatedWithMapsId( entity, propertyAnnotatedElement );
}
- return hasIdentifier;
+ return idPropertyCounter;
}
/*
@@ -1361,9 +1385,28 @@
final XClass returnedClass = inferredData.getClassOrElement();
+ //prepare PropertyBinder
+ PropertyBinder propertyBinder = new PropertyBinder();
+ propertyBinder.setName( inferredData.getPropertyName() );
+ propertyBinder.setReturnedClassName( inferredData.getTypeName() );
+ propertyBinder.setAccessType( inferredData.getDefaultAccess() );
+ propertyBinder.setHolder( propertyHolder );
+ propertyBinder.setProperty( property );
+ propertyBinder.setReturnedClass( inferredData.getPropertyClass() );
+ propertyBinder.setMappings( mappings );
+ if ( isIdentifierMapper ) {
+ propertyBinder.setInsertable( false );
+ propertyBinder.setUpdatable( false );
+ }
+ propertyBinder.setDeclaringClass( inferredData.getDeclaringClass() );
+ propertyBinder.setEntityBinder( entityBinder );
+ propertyBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
+
boolean isId = !entityBinder.isIgnoreIdAnnotations() &&
( property.isAnnotationPresent( Id.class )
|| property.isAnnotationPresent( EmbeddedId.class ) );
+ propertyBinder.setId( isId );
+
if ( property.isAnnotationPresent( Version.class ) ) {
if ( isIdentifierMapper ) {
throw new AnnotationException(
@@ -1384,19 +1427,14 @@
}
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() );
- propBinder.setColumns( columns );
- propBinder.setHolder( propertyHolder );
//PropertyHolderBuilder.buildPropertyHolder(rootClass)
- propBinder.setProperty( property );
- propBinder.setReturnedClass( inferredData.getPropertyClass() );
- propBinder.setMappings( mappings );
- propBinder.setDeclaringClass( inferredData.getDeclaringClass() );
- Property prop = propBinder.makePropertyValueAndBind();
- propBinder.getSimpleValueBinder().setVersion(true);
+// 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);
rootClass.setVersion( prop );
//If version is on a mapped superclass, update the mapping
@@ -1451,7 +1489,8 @@
ignoreNotFound, onDeleteCascade,
ToOneBinder.getTargetEntity( inferredData, mappings ),
propertyHolder,
- inferredData, false, isIdentifierMapper, inSecondPass, mappings
+ inferredData, false, isIdentifierMapper,
+ inSecondPass, propertyBinder, mappings
);
}
else if ( property.isAnnotationPresent( OneToOne.class ) ) {
@@ -1489,7 +1528,13 @@
ignoreNotFound, onDeleteCascade,
ToOneBinder.getTargetEntity( inferredData, mappings ),
propertyHolder,
- inferredData, ann.mappedBy(), trueOneToOne, isIdentifierMapper, inSecondPass,
mappings
+ inferredData,
+ ann.mappedBy(),
+ trueOneToOne,
+ isIdentifierMapper,
+ inSecondPass,
+ propertyBinder,
+ mappings
);
}
else if ( property.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
@@ -1793,7 +1838,7 @@
isComponent = property.isAnnotationPresent( Embedded.class )
|| property.isAnnotationPresent( EmbeddedId.class )
|| returnedClass.isAnnotationPresent( Embeddable.class );
- PropertyBinder propertyBinder;
+
if ( isComponent ) {
AccessType propertyAccessor = entityBinder.getPropertyAccessor( property );
propertyBinder = bindComponent(
@@ -1835,23 +1880,12 @@
mappings );
}
- propertyBinder = new PropertyBinder();
- propertyBinder.setName( inferredData.getPropertyName() );
- propertyBinder.setReturnedClassName( inferredData.getTypeName() );
propertyBinder.setLazy( lazy );
- propertyBinder.setAccessType( inferredData.getDefaultAccess() );
propertyBinder.setColumns( columns );
- propertyBinder.setHolder( propertyHolder );
- propertyBinder.setProperty( property );
- propertyBinder.setReturnedClass( inferredData.getPropertyClass() );
- propertyBinder.setMappings( mappings );
- if ( isIdentifierMapper ) {
- propertyBinder.setInsertable( false );
- propertyBinder.setUpdatable( false );
- }
- propertyBinder.setDeclaringClass( inferredData.getDeclaringClass() );
- propertyBinder.setId(isId);
- propertyBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
+// if ( isIdentifierMapper ) {
+// propertyBinder.setInsertable( false );
+// propertyBinder.setUpdatable( false );
+// }
propertyBinder.makePropertyValueAndBind();
}
if (isId) {
@@ -2105,6 +2139,7 @@
binder.setEmbedded( isComponentEmbedded );
binder.setHolder( propertyHolder );
binder.setId( isId );
+ binder.setEntityBinder( entityBinder );
binder.setInheritanceStatePerClass( inheritanceStatePerClass );
binder.setMappings( mappings );
binder.makePropertyAndBind();
@@ -2136,17 +2171,7 @@
* Because it's a value type, there is no bidirectional association, hence second
pass
* ordering does not matter
*/
- Component comp = new Component( propertyHolder.getPersistentClass() );
- comp.setEmbedded( isComponentEmbedded );
- //yuk
- comp.setTable( propertyHolder.getTable() );
- if ( !isIdentifierMapper ) {
- comp.setComponentClassName( inferredData.getClassOrElementName() );
- }
- else {
- comp.setComponentClassName( comp.getOwner().getClassName() );
- }
- comp.setNodeName( inferredData.getPropertyName() );
+ Component comp = createComponent( propertyHolder, inferredData, isComponentEmbedded,
isIdentifierMapper );
String subpath = BinderHelper.getPath( propertyHolder, inferredData );
log.trace( "Binding component with path: {}", subpath );
PropertyHolder subHolder = PropertyHolderBuilder.buildPropertyHolder(
@@ -2202,6 +2227,22 @@
return comp;
}
+ public static Component createComponent(PropertyHolder propertyHolder, PropertyData
inferredData, boolean isComponentEmbedded, boolean isIdentifierMapper) {
+ Component comp = new Component( propertyHolder.getPersistentClass() );
+ comp.setEmbedded( isComponentEmbedded );
+ //yuk
+ comp.setTable( propertyHolder.getTable() );
+ //FIXME shouldn't identifier mapper use getClassOrElementName? Need to be checked.
+ if ( isIdentifierMapper || ( isComponentEmbedded &&
inferredData.getPropertyName() == null ) ) {
+ comp.setComponentClassName( comp.getOwner().getClassName() );
+ }
+ else {
+ comp.setComponentClassName( inferredData.getClassOrElementName() );
+ }
+ comp.setNodeName( inferredData.getPropertyName() );
+ return comp;
+ }
+
private static void bindId(
String generatorType, String generatorName,
PropertyData inferredData, Ejb3Column[] columns, PropertyHolder propertyHolder,
@@ -2345,7 +2386,9 @@
String cascadeStrategy, Ejb3JoinColumn[] columns, boolean optional,
boolean ignoreNotFound, boolean cascadeOnDelete,
XClass targetEntity, PropertyHolder propertyHolder,
- PropertyData inferredData, boolean unique, boolean isIdentifierMapper, boolean
inSecondPass,
+ PropertyData inferredData, boolean unique,
+ boolean isIdentifierMapper, boolean inSecondPass,
+ PropertyBinder propertyBinder,
ExtendedMappings mappings
) {
//All FK columns should be in the same table
@@ -2399,24 +2442,26 @@
);
}
Ejb3Column.checkPropertyConsistency( columns, propertyHolder.getEntityName() +
propertyName );
- PropertyBinder binder = new PropertyBinder();
- binder.setName( propertyName );
- binder.setValue( value );
+ //PropertyBinder binder = new PropertyBinder();
+ propertyBinder.setName( propertyName );
+ propertyBinder.setValue( value );
//binder.setCascade(cascadeStrategy);
if ( isIdentifierMapper ) {
- binder.setInsertable( false );
- binder.setUpdatable( false );
+ propertyBinder.setInsertable( false );
+ propertyBinder.setUpdatable( false );
}
else {
- binder.setInsertable( columns[0].isInsertable() );
- binder.setUpdatable( columns[0].isUpdatable() );
+ propertyBinder.setInsertable( columns[0].isInsertable() );
+ propertyBinder.setUpdatable( columns[0].isUpdatable() );
}
- binder.setAccessType( inferredData.getDefaultAccess() );
- binder.setCascade( cascadeStrategy );
- binder.setProperty( property );
- Property prop = binder.makeProperty();
+ propertyBinder.setColumns( columns );
+ propertyBinder.setAccessType( inferredData.getDefaultAccess() );
+ propertyBinder.setCascade( cascadeStrategy );
+ propertyBinder.setProperty( property );
+ propertyBinder.setXToMany( true );
+ Property prop = propertyBinder.makePropertyAndBind();
//composite FK columns are in the same table so its OK
- propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() );
+ //propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() );
}
protected static void defineFetchingStrategy(ToOne toOne, XProperty property) {
@@ -2476,7 +2521,10 @@
PropertyHolder propertyHolder,
PropertyData inferredData, String mappedBy,
boolean trueOneToOne,
- boolean isIdentifierMapper, boolean inSecondPass, ExtendedMappings mappings
+ boolean isIdentifierMapper,
+ boolean inSecondPass,
+ PropertyBinder propertyBinder,
+ ExtendedMappings mappings
) {
//column.getTable() => persistentClass.getTable()
final String propertyName = inferredData.getPropertyName();
@@ -2535,7 +2583,8 @@
bindManyToOne(
cascadeStrategy, joinColumns, optional, ignoreNotFound, cascadeOnDelete,
targetEntity,
- propertyHolder, inferredData, true, isIdentifierMapper, inSecondPass, mappings
+ propertyHolder, inferredData, true, isIdentifierMapper, inSecondPass,
+ propertyBinder, mappings
);
}
}
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java 2010-01-25
16:23:59 UTC (rev 18618)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -119,7 +119,12 @@
private boolean ignoreIdAnnotations;
private boolean cacheLazyProperty;
private AccessType propertyAccessType = AccessType.DEFAULT;
+ private boolean wrapIdsInEmbeddedComponents;
+ public boolean wrapIdsInEmbeddedComponents() {
+ return wrapIdsInEmbeddedComponents;
+ }
+
/**
* Use as a fake one for Collection of elements
*/
@@ -413,6 +418,11 @@
}
}
+ public void setWrapIdsInEmbeddedComponents(boolean wrapIdsInEmbeddedComponents) {
+ this.wrapIdsInEmbeddedComponents = wrapIdsInEmbeddedComponents;
+ }
+
+
private static class EntityTableObjectNameSource implements ObjectNameSource {
private final String explicitName;
private final String logicalName;
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java 2010-01-25
16:23:59 UTC (rev 18618)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -40,11 +40,14 @@
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.cfg.AccessType;
+import org.hibernate.cfg.AnnotationBinder;
import org.hibernate.cfg.BinderHelper;
import org.hibernate.cfg.Ejb3Column;
import org.hibernate.cfg.ExtendedMappings;
import org.hibernate.cfg.InheritanceState;
import org.hibernate.cfg.PropertyHolder;
+import org.hibernate.cfg.PropertyPreloadedData;
+import org.hibernate.mapping.Component;
import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.PropertyGeneration;
@@ -73,15 +76,21 @@
private XClass declaringClass;
private boolean declaringClassSet;
private boolean embedded;
+ private EntityBinder entityBinder;
+ private boolean isXToMany;
public void setEmbedded(boolean embedded) {
this.embedded = embedded;
}
+ public void setEntityBinder(EntityBinder entityBinder) {
+ this.entityBinder = entityBinder;
+ }
+
/*
- * property can be null
- * prefer propertyName to property.getName() since some are overloaded
- */
+ * property can be null
+ * prefer propertyName to property.getName() since some are overloaded
+ */
private XProperty property;
private XClass returnedClass;
private boolean isId;
@@ -185,27 +194,45 @@
return bind( makePropertyAndValue() );
}
+ public void setXToMany(boolean xToMany) {
+ this.isXToMany = xToMany;
+ }
+
private Property bind(Property prop) {
if (isId) {
final RootClass rootClass = ( RootClass ) holder.getPersistentClass();
- rootClass.setIdentifier( ( KeyValue ) getValue() );
-
- if (embedded) {
- rootClass.setEmbeddedIdentifier( true );
+ //if an xToMany, it as to be wrapped today.
+ //FIXME this pose a problem as the PK is the class instead of the associated class
which is not really compliant with the spec
+ if ( isXToMany || entityBinder.wrapIdsInEmbeddedComponents() ) {
+ Component identifier = (Component) rootClass.getIdentifier();
+ if (identifier == null) {
+ identifier = AnnotationBinder.createComponent( holder, new
PropertyPreloadedData(null, null, null), true, false );
+ rootClass.setIdentifier( identifier );
+ identifier.setNullValue( "undefined" );
+ rootClass.setEmbeddedIdentifier( true );
+ }
+ //FIXME is it good enough?
+ identifier.addProperty( prop );
}
else {
- rootClass.setIdentifierProperty( prop );
- final org.hibernate.mapping.MappedSuperclass superclass =
BinderHelper.getMappedSuperclassOrNull(
- declaringClass,
- inheritanceStatePerClass,
- mappings
- );
- if (superclass != null) {
- superclass.setDeclaredIdentifierProperty(prop);
+ rootClass.setIdentifier( ( KeyValue ) getValue() );
+ if (embedded) {
+ rootClass.setEmbeddedIdentifier( true );
}
else {
- //we know the property is on the actual entity
- rootClass.setDeclaredIdentifierProperty( prop );
+ rootClass.setIdentifierProperty( prop );
+ final org.hibernate.mapping.MappedSuperclass superclass =
BinderHelper.getMappedSuperclassOrNull(
+ declaringClass,
+ inheritanceStatePerClass,
+ mappings
+ );
+ if (superclass != null) {
+ superclass.setDeclaredIdentifierProperty(prop);
+ }
+ else {
+ //we know the property is on the actual entity
+ rootClass.setDeclaredIdentifierProperty( prop );
+ }
}
}
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java 2010-01-25
16:23:59 UTC (rev 18618)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/Version.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -1,4 +1,4 @@
-// $Id:$
+// $Id$
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
@@ -24,6 +24,8 @@
*/
package org.hibernate.cfg.annotations;
+import java.util.Date;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -34,7 +36,7 @@
private static Logger log = LoggerFactory.getLogger( Version.class );
public static String getVersionString() {
- return "[WORKING]";
+ return "[WORKING]-1";
}
static {
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/Dependent.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/Dependent.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/Dependent.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -0,0 +1,25 @@
+package org.hibernate.test.annotations.derivedidentities.e1.c;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Dependent implements Serializable {
+
+ @Id
+ String name;
+
+
+ @Id
+ //@JoinColumn(name = "FK")
+ // id attribute mapped by join column default
+ @ManyToOne
+ Employee emp;
+
+}
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/DerivedIdentitySimpleParentEmbeddedDepTest.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/DerivedIdentitySimpleParentEmbeddedDepTest.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/DerivedIdentitySimpleParentEmbeddedDepTest.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -0,0 +1,46 @@
+package org.hibernate.test.annotations.derivedidentities.e1.c;
+
+import org.hibernate.Session;
+import org.hibernate.test.annotations.TestCase;
+import org.hibernate.test.util.SchemaUtil;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class DerivedIdentitySimpleParentEmbeddedDepTest extends TestCase {
+
+ public void testManyToOne() throws Exception {
+ assertTrue( SchemaUtil.isColumnPresent( "Dependent", "emp_empId",
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";
+ s.persist( d );
+ s.flush();
+ s.clear();
+ d = getDerivedClassById( e, s, Dependent.class, d.name );
+ assertEquals( e.empId, d.emp.empId );
+ s.getTransaction().rollback();
+ s.close();
+ }
+
+ private <T> T getDerivedClassById(Employee e, Session s, Class<T> clazz,
String name) {
+ return ( T )
+ s.createQuery( "from " + clazz.getName() + " d where d.name = :name
and d.emp.empId = :empId")
+ .setParameter( "empId", e.empId ).setParameter( "name", name
).uniqueResult();
+ }
+
+ @Override
+ protected Class<?>[] getAnnotatedClasses() {
+ return new Class<?>[] {
+ Dependent.class,
+ Employee.class
+ };
+ }
+}
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/Employee.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/Employee.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e1/c/Employee.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -0,0 +1,14 @@
+package org.hibernate.test.annotations.derivedidentities.e1.c;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Employee {
+ @Id
+ long empId;
+ String empName;
+}
Copied:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/DerivedIdentitySimpleParentSimpleDepTest.java
(from rev 18592,
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/DerivedIdentitySimpleParentSimpleDepTest.java)
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/DerivedIdentitySimpleParentSimpleDepTest.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/DerivedIdentitySimpleParentSimpleDepTest.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -0,0 +1,78 @@
+package org.hibernate.test.annotations.derivedidentities.e4.a;
+
+import java.util.Date;
+
+import org.hibernate.Session;
+import org.hibernate.test.annotations.TestCase;
+import org.hibernate.test.util.SchemaUtil;
+
+/**
+ * @author Emmanuel Bernard
+ */
+public class DerivedIdentitySimpleParentSimpleDepTest extends TestCase {
+
+ 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( );
+ 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();
+ 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();
+ }
+
+ 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( );
+ s.getTransaction().begin();
+ s.persist( e );
+ FinancialHistory d = new FinancialHistory();
+ d.patient = 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.close();
+ }
+
+ @Override
+ protected Class<?>[] getAnnotatedClasses() {
+ return new Class<?>[] {
+ MedicalHistory.class,
+ Simple.class,
+ Person.class,
+ FinancialHistory.class
+ };
+ }
+}
\ No newline at end of file
Copied:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/FinancialHistory.java
(from rev 18592,
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/b/FinancialHistory.java)
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/FinancialHistory.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/FinancialHistory.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -0,0 +1,28 @@
+package org.hibernate.test.annotations.derivedidentities.e4.a;
+
+import java.io.Serializable;
+import java.util.Date;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.ManyToOne;
+import javax.persistence.MapsId;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class FinancialHistory implements Serializable {
+
+ @Temporal(TemporalType.DATE)
+ Date lastupdate;
+
+ @Id
+ //@JoinColumn(name = "FK")
+ @ManyToOne
+ Person patient;
+
+}
\ No newline at end of file
Copied:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/MedicalHistory.java
(from rev 18592,
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/a/MedicalHistory.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/MedicalHistory.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -0,0 +1,27 @@
+package org.hibernate.test.annotations.derivedidentities.e4.a;
+
+import java.io.Serializable;
+import java.util.Date;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.JoinColumn;
+import javax.persistence.MapsId;
+import javax.persistence.OneToOne;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class MedicalHistory implements Serializable {
+
+ @Temporal(TemporalType.DATE)
+ Date lastupdate;
+
+ @Id
+ @JoinColumn(name = "FK")
+ @OneToOne
+ Person patient;
+}
\ No newline at end of file
Copied:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Person.java
(from rev 18592,
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/a/Person.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Person.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -0,0 +1,14 @@
+package org.hibernate.test.annotations.derivedidentities.e4.a;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Person {
+ @Id
+ String ssn;
+}
\ No newline at end of file
Added:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Simple.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Simple.java
(rev 0)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/derivedidentities/e4/a/Simple.java 2010-01-25
17:19:05 UTC (rev 18619)
@@ -0,0 +1,17 @@
+package org.hibernate.test.annotations.derivedidentities.e4.a;
+
+import java.io.Serializable;
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+/**
+ * @author Emmanuel Bernard
+ */
+@Entity
+public class Simple
+ implements Serializable {
+ @Id
+ String ssn;
+ @Id
+ String name;
+}