HHH-4529 clean @Id/@EmbeddedId mapping and merge with the regular basic and component mapping to open possibilities for @Id @ManyToOne support

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18600 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Emmanuel Bernard 2010-01-21 17:51:09 +00:00
parent 174a568f8f
commit 8577a68e69
7 changed files with 198 additions and 110 deletions

View File

@ -1253,27 +1253,11 @@ public final class AnnotationBinder {
} }
final XClass returnedClass = inferredData.getClassOrElement(); final XClass returnedClass = inferredData.getClassOrElement();
boolean isId;
if ( !entityBinder.isIgnoreIdAnnotations() && boolean isId = !entityBinder.isIgnoreIdAnnotations() &&
( property.isAnnotationPresent( Id.class ) ( property.isAnnotationPresent( Id.class )
|| property.isAnnotationPresent( EmbeddedId.class ) ) ) { || property.isAnnotationPresent( EmbeddedId.class ) );
isId = true; if ( property.isAnnotationPresent( Version.class ) ) {
//Override from @MapsId if needed
columns = overrideColumnFromMapsIdProperty( "", columns, propertyHolder, entityBinder, mappings );
processId(
propertyHolder,
property,
inferredData,
classGenerators,
entityBinder,
isIdentifierMapper,
mappings,
inheritanceStatePerClass,
columns,
returnedClass
);
}
else if ( property.isAnnotationPresent( Version.class ) ) {
if ( isIdentifierMapper ) { if ( isIdentifierMapper ) {
throw new AnnotationException( throw new AnnotationException(
"@IdClass class should not have @Version property" "@IdClass class should not have @Version property"
@ -1304,7 +1288,7 @@ public final class AnnotationBinder {
propBinder.setReturnedClass( inferredData.getPropertyClass() ); propBinder.setReturnedClass( inferredData.getPropertyClass() );
propBinder.setMappings( mappings ); propBinder.setMappings( mappings );
propBinder.setDeclaringClass( inferredData.getDeclaringClass() ); propBinder.setDeclaringClass( inferredData.getDeclaringClass() );
Property prop = propBinder.bind(); Property prop = propBinder.makePropertyValueAndBind();
propBinder.getSimpleValueBinder().setVersion(true); propBinder.getSimpleValueBinder().setVersion(true);
rootClass.setVersion( prop ); rootClass.setVersion( prop );
@ -1695,19 +1679,26 @@ public final class AnnotationBinder {
collectionBinder.bind(); collectionBinder.bind();
} }
else { //Either a regular property or a basic @Id or @EmbeddedId while not ignoring id annotations
else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) {
//define whether the type is a component or not //define whether the type is a component or not
boolean isComponent; boolean isComponent;
Embeddable embeddableAnn = returnedClass.getAnnotation( Embeddable.class ); isComponent = property.isAnnotationPresent( Embedded.class )
Embedded embeddedAnn = property.getAnnotation( Embedded.class ); || property.isAnnotationPresent( EmbeddedId.class )
isComponent = embeddedAnn != null || embeddableAnn != null; || returnedClass.isAnnotationPresent( Embeddable.class );
PropertyBinder propertyBinder;
if ( isComponent ) { if ( isComponent ) {
AccessType propertyAccessor = entityBinder.getPropertyAccessor( property ); AccessType propertyAccessor = entityBinder.getPropertyAccessor( property );
bindComponent( propertyBinder = bindComponent(
inferredData, propertyHolder, propertyAccessor, entityBinder, inferredData,
propertyHolder,
propertyAccessor,
entityBinder,
isIdentifierMapper, isIdentifierMapper,
mappings, isComponentEmbedded, inheritanceStatePerClass mappings,
isComponentEmbedded,
isId,
inheritanceStatePerClass
); );
} }
else { else {
@ -1720,35 +1711,53 @@ public final class AnnotationBinder {
lazy = ann.fetch() == FetchType.LAZY; lazy = ann.fetch() == FetchType.LAZY;
} }
//implicit type will check basic types and Serializable classes //implicit type will check basic types and Serializable classes
if ( !optional && nullability != Nullability.FORCED_NULL ) { if ( isId || ( !optional && nullability != Nullability.FORCED_NULL ) ) {
//force columns to not null //force columns to not null
for (Ejb3Column col : columns) { for (Ejb3Column col : columns) {
col.forceNotNull(); col.forceNotNull();
} }
} }
//Override from @MapsId if needed //Override from @MapsId if needed
if ( propertyHolder.isOrWithinEmbeddedId() ) { if ( isId || propertyHolder.isOrWithinEmbeddedId() ) {
columns = overrideColumnFromMapsIdProperty( property.getName(), columns, propertyHolder, entityBinder, mappings ); columns = overrideColumnFromMapsIdProperty(
isId ? "" : property.getName(), //@MapsId("") points to the id property
columns,
propertyHolder,
entityBinder,
mappings );
} }
PropertyBinder propBinder = new PropertyBinder(); propertyBinder = new PropertyBinder();
propBinder.setName( inferredData.getPropertyName() ); propertyBinder.setName( inferredData.getPropertyName() );
propBinder.setReturnedClassName( inferredData.getTypeName() ); propertyBinder.setReturnedClassName( inferredData.getTypeName() );
propBinder.setLazy( lazy ); propertyBinder.setLazy( lazy );
propBinder.setAccessType( inferredData.getDefaultAccess() ); propertyBinder.setAccessType( inferredData.getDefaultAccess() );
propBinder.setColumns( columns ); propertyBinder.setColumns( columns );
propBinder.setHolder( propertyHolder ); propertyBinder.setHolder( propertyHolder );
propBinder.setProperty( property ); propertyBinder.setProperty( property );
propBinder.setReturnedClass( inferredData.getPropertyClass() ); propertyBinder.setReturnedClass( inferredData.getPropertyClass() );
propBinder.setMappings( mappings ); propertyBinder.setMappings( mappings );
if ( isIdentifierMapper ) { if ( isIdentifierMapper ) {
propBinder.setInsertable( false ); propertyBinder.setInsertable( false );
propBinder.setUpdatable( false ); propertyBinder.setUpdatable( false );
} }
propBinder.setDeclaringClass( inferredData.getDeclaringClass() ); propertyBinder.setDeclaringClass( inferredData.getDeclaringClass() );
propBinder.bind(); propertyBinder.setId(isId);
propertyBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
propertyBinder.makePropertyValueAndBind();
}
if (isId) {
//components and regular basic types create SimpleValue objects
final SimpleValue value = ( SimpleValue ) propertyBinder.getValue();
processId(
propertyHolder,
inferredData,
value,
classGenerators,
isIdentifierMapper,
mappings
);
} }
} }
//init index //init index
@ -1785,14 +1794,15 @@ public final class AnnotationBinder {
} }
} }
private static void processId(PropertyHolder propertyHolder, XProperty property, PropertyData inferredData, HashMap<String, IdGenerator> classGenerators, EntityBinder entityBinder, boolean isIdentifierMapper, ExtendedMappings mappings, Map<XClass, InheritanceState> inheritanceStatePerClass, Ejb3Column[] columns, XClass returnedClass) { private static void processId(PropertyHolder propertyHolder, PropertyData inferredData, SimpleValue idValue, HashMap<String, IdGenerator> classGenerators, boolean isIdentifierMapper, ExtendedMappings mappings) {
if ( isIdentifierMapper ) { if ( isIdentifierMapper ) {
throw new AnnotationException( throw new AnnotationException(
"@IdClass class should not have @Id nor @EmbeddedId properties: " "@IdClass class should not have @Id nor @EmbeddedId properties: "
+ BinderHelper.getPath( propertyHolder, inferredData ) + BinderHelper.getPath( propertyHolder, inferredData )
); );
} }
log.trace( "{} is an id", inferredData.getPropertyName() ); XClass returnedClass = inferredData.getClassOrElement();
XProperty property = inferredData.getProperty();
//clone classGenerator and override with local values //clone classGenerator and override with local values
HashMap<String, IdGenerator> localGenerators = (HashMap<String, IdGenerator>) classGenerators.clone(); HashMap<String, IdGenerator> localGenerators = (HashMap<String, IdGenerator>) classGenerators.clone();
localGenerators.putAll( buildLocalGenerators( property, mappings ) ); localGenerators.putAll( buildLocalGenerators( property, mappings ) );
@ -1801,31 +1811,16 @@ public final class AnnotationBinder {
//guess if its a component and find id data access (property, field etc) //guess if its a component and find id data access (property, field etc)
final boolean isComponent = returnedClass.isAnnotationPresent( Embeddable.class ) final boolean isComponent = returnedClass.isAnnotationPresent( Embeddable.class )
|| property.isAnnotationPresent( EmbeddedId.class ); || property.isAnnotationPresent( EmbeddedId.class );
AccessType propertyAccessor = entityBinder.getPropertyAccessor( returnedClass );
GeneratedValue generatedValue = property.getAnnotation( GeneratedValue.class ); GeneratedValue generatedValue = property.getAnnotation( GeneratedValue.class );
String generatorType = generatedValue != null ? String generatorType = generatedValue != null ?
generatorType( generatedValue.strategy() ) : generatorType( generatedValue.strategy() ) :
"assigned"; "assigned";
String generator = generatedValue != null ? String generatorName = generatedValue != null ?
generatedValue.generator() : generatedValue.generator() :
BinderHelper.ANNOTATION_STRING_DEFAULT; BinderHelper.ANNOTATION_STRING_DEFAULT;
if ( isComponent ) generatorType = "assigned"; //a component must not have any generator if ( isComponent ) generatorType = "assigned"; //a component must not have any generator
BinderHelper.makeIdGenerator( idValue, generatorType, generatorName, mappings, localGenerators );
bindId(
generatorType,
generator,
inferredData,
columns,
propertyHolder,
localGenerators,
isComponent,
propertyAccessor, entityBinder,
false,
isIdentifierMapper,
mappings,
inheritanceStatePerClass
);
log.trace( log.trace(
"Bind {} on {}", ( isComponent ? "@EmbeddedId" : "@Id" ), inferredData.getPropertyName() "Bind {} on {}", ( isComponent ? "@EmbeddedId" : "@Id" ), inferredData.getPropertyName()
@ -1963,29 +1958,50 @@ public final class AnnotationBinder {
collectionBinder.setInverseJoinColumns( inverseJoinColumns ); collectionBinder.setInverseJoinColumns( inverseJoinColumns );
} }
private static void bindComponent( private static PropertyBinder bindComponent(
PropertyData inferredData, PropertyData inferredData,
PropertyHolder propertyHolder, PropertyHolder propertyHolder,
AccessType propertyAccessor, EntityBinder entityBinder, AccessType propertyAccessor,
EntityBinder entityBinder,
boolean isIdentifierMapper, boolean isIdentifierMapper,
ExtendedMappings mappings, boolean isComponentEmbedded, ExtendedMappings mappings,
boolean isComponentEmbedded,
boolean isId,
Map<XClass, InheritanceState> inheritanceStatePerClass Map<XClass, InheritanceState> inheritanceStatePerClass
) { ) {
Component comp = fillComponent( Component comp = fillComponent(
propertyHolder, inferredData, propertyAccessor, true, entityBinder, propertyHolder, inferredData, propertyAccessor, !isId, entityBinder,
isComponentEmbedded, isIdentifierMapper, isComponentEmbedded, isIdentifierMapper,
false, mappings, inheritanceStatePerClass false, mappings, inheritanceStatePerClass
); );
if (isId) {
comp.setKey( true );
if ( propertyHolder.getPersistentClass().getIdentifier() != null ) {
throw new AnnotationException(
comp.getComponentClassName()
+ " must not have @Id properties when used as an @EmbeddedId: "
+ BinderHelper.getPath( propertyHolder, inferredData ) );
}
if ( comp.getPropertySpan() == 0 ) {
throw new AnnotationException( comp.getComponentClassName()
+ " has no persistent id property"
+ BinderHelper.getPath( propertyHolder, inferredData ) );
}
}
XProperty property = inferredData.getProperty(); XProperty property = inferredData.getProperty();
setupComponentTuplizer( property, comp ); setupComponentTuplizer( property, comp );
PropertyBinder binder = new PropertyBinder(); PropertyBinder binder = new PropertyBinder();
binder.setName( inferredData.getPropertyName() ); binder.setName( inferredData.getPropertyName() );
binder.setValue( comp ); binder.setValue( comp );
binder.setProperty( inferredData.getProperty() ); binder.setProperty( inferredData.getProperty() );
binder.setAccessType( inferredData.getDefaultAccess() ); binder.setAccessType( inferredData.getDefaultAccess() );
Property prop = binder.make(); binder.setEmbedded( isComponentEmbedded );
propertyHolder.addProperty( prop, inferredData.getDeclaringClass() ); binder.setHolder( propertyHolder );
binder.setId( isId );
binder.setInheritanceStatePerClass( inheritanceStatePerClass );
binder.setMappings( mappings );
binder.makePropertyAndBind();
return binder;
} }
public static Component fillComponent( public static Component fillComponent(
@ -2159,7 +2175,7 @@ public final class AnnotationBinder {
binder.setValue( id ); binder.setValue( id );
binder.setAccessType( inferredData.getDefaultAccess() ); binder.setAccessType( inferredData.getDefaultAccess() );
binder.setProperty( inferredData.getProperty() ); binder.setProperty( inferredData.getProperty() );
Property prop = binder.make(); Property prop = binder.makeProperty();
rootClass.setIdentifierProperty( prop ); rootClass.setIdentifierProperty( prop );
//if the id property is on a superclass, update the metamodel //if the id property is on a superclass, update the metamodel
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull( final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
@ -2291,7 +2307,7 @@ public final class AnnotationBinder {
binder.setAccessType( inferredData.getDefaultAccess() ); binder.setAccessType( inferredData.getDefaultAccess() );
binder.setCascade( cascadeStrategy ); binder.setCascade( cascadeStrategy );
binder.setProperty( property ); binder.setProperty( property );
Property prop = binder.make(); Property prop = binder.makeProperty();
//composite FK columns are in the same table so its OK //composite FK columns are in the same table so its OK
propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() ); propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() );
} }
@ -2446,7 +2462,7 @@ public final class AnnotationBinder {
} }
binder.setAccessType( inferredData.getDefaultAccess() ); binder.setAccessType( inferredData.getDefaultAccess() );
binder.setCascade( cascadeStrategy ); binder.setCascade( cascadeStrategy );
Property prop = binder.make(); Property prop = binder.makeProperty();
//composite FK columns are in the same table so its OK //composite FK columns are in the same table so its OK
propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() ); propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() );
} }

View File

@ -72,7 +72,7 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) { public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
//Ejb3Column.checkPropertyConsistency( ); //already called earlier //Ejb3Column.checkPropertyConsistency( ); //already called earlier
if ( columns[0].isSecondary() ) { if ( columns != null && columns[0].isSecondary() ) {
//TODO move the getJoin() code here? //TODO move the getJoin() code here?
final Join join = columns[0].getJoin(); final Join join = columns[0].getJoin();
addPropertyToJoin( prop, declaringClass, join ); addPropertyToJoin( prop, declaringClass, join );

View File

@ -61,6 +61,7 @@ public class ComponentPropertyHolder extends AbstractPropertyHolder {
* if not, change the component table if no properties are set * if not, change the component table if no properties are set
* if a property is set already the core cannot support that * if a property is set already the core cannot support that
*/ */
if (columns != null) {
Table table = columns[0].getTable(); Table table = columns[0].getTable();
if ( !table.equals( component.getTable() ) ) { if ( !table.equals( component.getTable() ) ) {
if ( component.getPropertySpan() == 0 ) { if ( component.getPropertySpan() == 0 ) {
@ -73,6 +74,7 @@ public class ComponentPropertyHolder extends AbstractPropertyHolder {
); );
} }
} }
}
addProperty( prop, declaringClass ); addProperty( prop, declaringClass );
} }

View File

@ -106,7 +106,7 @@ public class OneToOneSecondPass implements SecondPass {
binder.setValue( value ); binder.setValue( value );
binder.setCascade( cascadeStrategy ); binder.setCascade( cascadeStrategy );
binder.setAccessType( inferredData.getDefaultAccess() ); binder.setAccessType( inferredData.getDefaultAccess() );
Property prop = binder.make(); Property prop = binder.makeProperty();
if ( BinderHelper.isDefault( mappedBy ) ) { if ( BinderHelper.isDefault( mappedBy ) ) {
/* /*
* we need to check if the columns are in the right order * we need to check if the columns are in the right order

View File

@ -522,7 +522,7 @@ public abstract class CollectionBinder {
binder.setProperty( property ); binder.setProperty( property );
binder.setInsertable( insertable ); binder.setInsertable( insertable );
binder.setUpdatable( updatable ); binder.setUpdatable( updatable );
Property prop = binder.make(); Property prop = binder.makeProperty();
//we don't care about the join stuffs because the column is on the association table. //we don't care about the join stuffs because the column is on the association table.
if (! declaringClassSet) throw new AssertionFailure( "DeclaringClass is not set in CollectionBinder while binding" ); if (! declaringClassSet) throw new AssertionFailure( "DeclaringClass is not set in CollectionBinder while binding" );
propertyHolder.addProperty( prop, declaringClass ); propertyHolder.addProperty( prop, declaringClass );

View File

@ -23,29 +23,35 @@
*/ */
package org.hibernate.cfg.annotations; package org.hibernate.cfg.annotations;
import java.util.Map;
import javax.persistence.EmbeddedId; import javax.persistence.EmbeddedId;
import javax.persistence.Id; import javax.persistence.Id;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.annotations.Generated; import org.hibernate.annotations.Generated;
import org.hibernate.annotations.GenerationTime; import org.hibernate.annotations.GenerationTime;
import org.hibernate.annotations.Immutable; import org.hibernate.annotations.Immutable;
import org.hibernate.annotations.NaturalId; import org.hibernate.annotations.NaturalId;
import org.hibernate.annotations.OptimisticLock; import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty; import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.cfg.AccessType; import org.hibernate.cfg.AccessType;
import org.hibernate.cfg.BinderHelper;
import org.hibernate.cfg.Ejb3Column; import org.hibernate.cfg.Ejb3Column;
import org.hibernate.cfg.ExtendedMappings; import org.hibernate.cfg.ExtendedMappings;
import org.hibernate.cfg.InheritanceState;
import org.hibernate.cfg.PropertyHolder; import org.hibernate.cfg.PropertyHolder;
import org.hibernate.mapping.KeyValue;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.mapping.RootClass;
import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value; import org.hibernate.mapping.Value;
import org.hibernate.util.StringHelper; import org.hibernate.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
@ -66,6 +72,11 @@ public class PropertyBinder {
private SimpleValueBinder simpleValueBinder; private SimpleValueBinder simpleValueBinder;
private XClass declaringClass; private XClass declaringClass;
private boolean declaringClassSet; private boolean declaringClassSet;
private boolean embedded;
public void setEmbedded(boolean embedded) {
this.embedded = embedded;
}
/* /*
* property can be null * property can be null
@ -73,6 +84,9 @@ public class PropertyBinder {
*/ */
private XProperty property; private XProperty property;
private XClass returnedClass; private XClass returnedClass;
private boolean isId;
private Map<XClass, InheritanceState> inheritanceStatePerClass;
private Property mappingProperty;
public void setInsertable(boolean insertable) { public void setInsertable(boolean insertable) {
this.insertable = insertable; this.insertable = insertable;
@ -82,7 +96,6 @@ public class PropertyBinder {
this.updatable = updatable; this.updatable = updatable;
} }
public void setName(String name) { public void setName(String name) {
this.name = name; this.name = name;
} }
@ -129,8 +142,10 @@ public class PropertyBinder {
private void validateBind() { private void validateBind() {
if ( property.isAnnotationPresent( Immutable.class ) ) { if ( property.isAnnotationPresent( Immutable.class ) ) {
throw new AnnotationException("@Immutable on property not allowed. " + throw new AnnotationException(
"Only allowed on entity level or on a collection."); "@Immutable on property not allowed. " +
"Only allowed on entity level or on a collection."
);
} }
if ( !declaringClassSet ) { if ( !declaringClassSet ) {
throw new AssertionFailure( "declaringClass has not been set before a bind" ); throw new AssertionFailure( "declaringClass has not been set before a bind" );
@ -141,7 +156,7 @@ public class PropertyBinder {
//TODO check necessary params for a make //TODO check necessary params for a make
} }
public Property bind() { private Property makePropertyAndValue() {
validateBind(); validateBind();
log.debug( "binding property {} with lazy={}", name, lazy ); log.debug( "binding property {} with lazy={}", name, lazy );
String containerClassName = holder == null ? String containerClassName = holder == null ?
@ -157,12 +172,51 @@ public class PropertyBinder {
simpleValueBinder.setMappings( mappings ); simpleValueBinder.setMappings( mappings );
SimpleValue propertyValue = simpleValueBinder.make(); SimpleValue propertyValue = simpleValueBinder.make();
setValue( propertyValue ); setValue( propertyValue );
Property prop = make(); return makeProperty();
}
//used when value is provided
public Property makePropertyAndBind() {
return bind( makeProperty() );
}
//used to build everything from scratch
public Property makePropertyValueAndBind() {
return bind( makePropertyAndValue() );
}
private Property bind(Property prop) {
if (isId) {
final RootClass rootClass = ( RootClass ) holder.getPersistentClass();
rootClass.setIdentifier( ( KeyValue ) getValue() );
if (embedded) {
rootClass.setEmbeddedIdentifier( true );
}
else {
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 );
}
}
}
else {
holder.addProperty( prop, columns, declaringClass ); holder.addProperty( prop, columns, declaringClass );
}
return prop; return prop;
} }
public Property make() { //used when the value is provided and the binding is done elsewhere
public Property makeProperty() {
validateMake(); validateMake();
log.debug( "Building property " + name ); log.debug( "Building property " + name );
Property prop = new Property(); Property prop = new Property();
@ -182,8 +236,10 @@ public class PropertyBinder {
if ( !GenerationTime.NEVER.equals( generated ) ) { if ( !GenerationTime.NEVER.equals( generated ) ) {
if ( property.isAnnotationPresent( javax.persistence.Version.class ) if ( property.isAnnotationPresent( javax.persistence.Version.class )
&& GenerationTime.INSERT.equals( generated ) ) { && GenerationTime.INSERT.equals( generated ) ) {
throw new AnnotationException( "@Generated(INSERT) on a @Version property not allowed, use ALWAYS: " throw new AnnotationException(
+ StringHelper.qualify( holder.getPath(), name ) ); "@Generated(INSERT) on a @Version property not allowed, use ALWAYS: "
+ StringHelper.qualify( holder.getPath(), name )
);
} }
insertable = false; insertable = false;
if ( GenerationTime.ALWAYS.equals( generated ) ) { if ( GenerationTime.ALWAYS.equals( generated ) ) {
@ -213,11 +269,14 @@ public class PropertyBinder {
property.isAnnotationPresent( javax.persistence.Version.class ) property.isAnnotationPresent( javax.persistence.Version.class )
|| property.isAnnotationPresent( Id.class ) || property.isAnnotationPresent( Id.class )
|| property.isAnnotationPresent( EmbeddedId.class ) ) ) { || property.isAnnotationPresent( EmbeddedId.class ) ) ) {
throw new AnnotationException( "@OptimisticLock.exclude=true incompatible with @Id, @EmbeddedId and @Version: " throw new AnnotationException(
+ StringHelper.qualify( holder.getPath(), name ) ); "@OptimisticLock.exclude=true incompatible with @Id, @EmbeddedId and @Version: "
+ StringHelper.qualify( holder.getPath(), name )
);
} }
} }
log.trace( "Cascading " + name + " with " + cascade ); log.trace( "Cascading " + name + " with " + cascade );
this.mappingProperty = prop;
return prop; return prop;
} }
@ -233,4 +292,15 @@ public class PropertyBinder {
return simpleValueBinder; return simpleValueBinder;
} }
public Value getValue() {
return value;
}
public void setId(boolean id) {
this.isId = id;
}
public void setInheritanceStatePerClass(Map<XClass, InheritanceState> inheritanceStatePerClass) {
this.inheritanceStatePerClass = inheritanceStatePerClass;
}
} }

View File

@ -9,7 +9,7 @@ import org.hibernate.test.util.SchemaUtil;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
*/ */
public class DerivedIdentitySimpleParentSimpleDepTest extends TestCase { public class DerivedIdentitySimpleParentSimpleDepMapsIdTest extends TestCase {
public void testOneToOneExplicitJoinColumn() throws Exception { public void testOneToOneExplicitJoinColumn() throws Exception {
assertTrue( SchemaUtil.isColumnPresent( "MedicalHistory", "FK", getCfg() ) ); assertTrue( SchemaUtil.isColumnPresent( "MedicalHistory", "FK", getCfg() ) );