HHH-4529 Support for basic @MapsId on simple id on both parent and derived (example 4.a). However I am losing the creation of the FK constraint.
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18583 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
aa9dd93555
commit
6588ede3a7
|
@ -56,6 +56,7 @@ import javax.persistence.ManyToMany;
|
||||||
import javax.persistence.ManyToOne;
|
import javax.persistence.ManyToOne;
|
||||||
import javax.persistence.MapKey;
|
import javax.persistence.MapKey;
|
||||||
import javax.persistence.MappedSuperclass;
|
import javax.persistence.MappedSuperclass;
|
||||||
|
import javax.persistence.MapsId;
|
||||||
import javax.persistence.NamedNativeQueries;
|
import javax.persistence.NamedNativeQueries;
|
||||||
import javax.persistence.NamedNativeQuery;
|
import javax.persistence.NamedNativeQuery;
|
||||||
import javax.persistence.NamedQueries;
|
import javax.persistence.NamedQueries;
|
||||||
|
@ -891,7 +892,7 @@ public final class AnnotationBinder {
|
||||||
boolean hasIdentifier = false;
|
boolean hasIdentifier = false;
|
||||||
|
|
||||||
for ( int index = 0; index < deep; index++ ) {
|
for ( int index = 0; index < deep; index++ ) {
|
||||||
PropertyContainer properyContainer = new PropertyContainer( classesToProcess.get( index ) );
|
PropertyContainer properyContainer = new PropertyContainer( classesToProcess.get( index ), clazzToProcess );
|
||||||
boolean currentHasIdentifier = addElementsOfClass( elements, accessType, properyContainer, mappings );
|
boolean currentHasIdentifier = addElementsOfClass( elements, accessType, properyContainer, mappings );
|
||||||
hasIdentifier = hasIdentifier || currentHasIdentifier;
|
hasIdentifier = hasIdentifier || currentHasIdentifier;
|
||||||
}
|
}
|
||||||
|
@ -1116,7 +1117,7 @@ public final class AnnotationBinder {
|
||||||
Collection<XProperty> properties = propertyContainer.getProperties( accessType );
|
Collection<XProperty> properties = propertyContainer.getProperties( accessType );
|
||||||
for ( XProperty p : properties ) {
|
for ( XProperty p : properties ) {
|
||||||
final boolean currentHasIdentifier = addProperty(
|
final boolean currentHasIdentifier = addProperty(
|
||||||
propertyContainer.getXClass(), p, elements, accessType.getType(), mappings
|
propertyContainer, p, elements, accessType.getType(), mappings
|
||||||
);
|
);
|
||||||
hasIdentifier = hasIdentifier || currentHasIdentifier;
|
hasIdentifier = hasIdentifier || currentHasIdentifier;
|
||||||
}
|
}
|
||||||
|
@ -1124,9 +1125,11 @@ public final class AnnotationBinder {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean addProperty(
|
private static boolean addProperty(
|
||||||
XClass declaringClass, XProperty property, List<PropertyData> annElts,
|
PropertyContainer propertyContainer, XProperty property, List<PropertyData> annElts,
|
||||||
String propertyAccessor, ExtendedMappings mappings
|
String propertyAccessor, ExtendedMappings mappings
|
||||||
) {
|
) {
|
||||||
|
final XClass declaringClass = propertyContainer.getDeclaringClass();
|
||||||
|
final XClass entity = propertyContainer.getEntityAtStake();
|
||||||
boolean hasIdentifier;
|
boolean hasIdentifier;
|
||||||
PropertyData propertyAnnotatedElement = new PropertyInferredData(
|
PropertyData propertyAnnotatedElement = new PropertyInferredData(
|
||||||
declaringClass, property, propertyAccessor,
|
declaringClass, property, propertyAccessor,
|
||||||
|
@ -1145,6 +1148,9 @@ public final class AnnotationBinder {
|
||||||
annElts.add( propertyAnnotatedElement );
|
annElts.add( propertyAnnotatedElement );
|
||||||
hasIdentifier = false;
|
hasIdentifier = false;
|
||||||
}
|
}
|
||||||
|
if ( element.isAnnotationPresent( MapsId.class ) ) {
|
||||||
|
mappings.addPropertyAnnotatedWithMapsId( entity, propertyAnnotatedElement );
|
||||||
|
}
|
||||||
|
|
||||||
return hasIdentifier;
|
return hasIdentifier;
|
||||||
}
|
}
|
||||||
|
@ -1166,7 +1172,7 @@ public final class AnnotationBinder {
|
||||||
* ordering does not matter
|
* ordering does not matter
|
||||||
*/
|
*/
|
||||||
Ejb3Column[] columns = null;
|
Ejb3Column[] columns = null;
|
||||||
Ejb3JoinColumn[] joinColumns = null;
|
|
||||||
log.debug(
|
log.debug(
|
||||||
"Processing annotations of {}.{}", propertyHolder.getEntityName(), inferredData.getPropertyName()
|
"Processing annotations of {}.{}", propertyHolder.getEntityName(), inferredData.getPropertyName()
|
||||||
);
|
);
|
||||||
|
@ -1183,36 +1189,11 @@ public final class AnnotationBinder {
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Ejb3JoinColumn[] joinColumns = buildExplicitJoinColumns(
|
||||||
|
propertyHolder, property, inferredData, entityBinder, mappings
|
||||||
|
);
|
||||||
|
|
||||||
//process @JoinColumn(s) before @Column(s) to handle collection of entities properly
|
|
||||||
{
|
|
||||||
JoinColumn[] anns = null;
|
|
||||||
|
|
||||||
if ( property.isAnnotationPresent( JoinColumn.class ) ) {
|
|
||||||
anns = new JoinColumn[] { property.getAnnotation( JoinColumn.class ) };
|
|
||||||
}
|
|
||||||
else if ( property.isAnnotationPresent( JoinColumns.class ) ) {
|
|
||||||
JoinColumns ann = property.getAnnotation( JoinColumns.class );
|
|
||||||
anns = ann.value();
|
|
||||||
int length = anns.length;
|
|
||||||
if ( length == 0 ) {
|
|
||||||
throw new AnnotationException( "Cannot bind an empty @JoinColumns" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( anns != null ) {
|
|
||||||
joinColumns = Ejb3JoinColumn.buildJoinColumns(
|
|
||||||
anns, null, entityBinder.getSecondaryTables(),
|
|
||||||
propertyHolder, inferredData.getPropertyName(), mappings
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if ( property.isAnnotationPresent( JoinColumnsOrFormulas.class ) ) {
|
|
||||||
JoinColumnsOrFormulas ann = property.getAnnotation( JoinColumnsOrFormulas.class );
|
|
||||||
joinColumns = Ejb3JoinColumn.buildJoinColumnsOrFormulas(
|
|
||||||
ann, null, entityBinder.getSecondaryTables(),
|
|
||||||
propertyHolder, inferredData.getPropertyName(), mappings
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent( Formula.class ) ) {
|
if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent( Formula.class ) ) {
|
||||||
Column ann = property.getAnnotation( Column.class );
|
Column ann = property.getAnnotation( Column.class );
|
||||||
Formula formulaAnn = property.getAnnotation( Formula.class );
|
Formula formulaAnn = property.getAnnotation( Formula.class );
|
||||||
|
@ -1234,30 +1215,9 @@ public final class AnnotationBinder {
|
||||||
( property.isAnnotationPresent( ManyToOne.class )
|
( property.isAnnotationPresent( ManyToOne.class )
|
||||||
|| property.isAnnotationPresent( OneToOne.class ) )
|
|| property.isAnnotationPresent( OneToOne.class ) )
|
||||||
) {
|
) {
|
||||||
JoinTable joinTableAnn = propertyHolder.getJoinTable( property );
|
joinColumns = buildDefaultJoinColumnsForXToOne(
|
||||||
if ( joinTableAnn != null ) {
|
propertyHolder, property, inferredData, entityBinder, mappings
|
||||||
joinColumns = Ejb3JoinColumn.buildJoinColumns(
|
);
|
||||||
joinTableAnn.inverseJoinColumns(), null, entityBinder.getSecondaryTables(),
|
|
||||||
propertyHolder, inferredData.getPropertyName(), mappings
|
|
||||||
);
|
|
||||||
if ( StringHelper.isEmpty( joinTableAnn.name() ) ) {
|
|
||||||
throw new AnnotationException(
|
|
||||||
"JoinTable.name() on a @ToOne association has to be explicit: "
|
|
||||||
+ StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() )
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
OneToOne oneToOneAnn = property.getAnnotation( OneToOne.class );
|
|
||||||
String mappedBy = oneToOneAnn != null ?
|
|
||||||
oneToOneAnn.mappedBy() :
|
|
||||||
null;
|
|
||||||
joinColumns = Ejb3JoinColumn.buildJoinColumns(
|
|
||||||
(JoinColumn[]) null,
|
|
||||||
mappedBy, entityBinder.getSecondaryTables(),
|
|
||||||
propertyHolder, inferredData.getPropertyName(), mappings
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if ( joinColumns == null &&
|
else if ( joinColumns == null &&
|
||||||
( property.isAnnotationPresent( OneToMany.class )
|
( property.isAnnotationPresent( OneToMany.class )
|
||||||
|
@ -1843,6 +1803,69 @@ public final class AnnotationBinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Ejb3JoinColumn[] buildDefaultJoinColumnsForXToOne(PropertyHolder propertyHolder, XProperty property, PropertyData inferredData, EntityBinder entityBinder, ExtendedMappings mappings) {
|
||||||
|
Ejb3JoinColumn[] joinColumns;
|
||||||
|
JoinTable joinTableAnn = propertyHolder.getJoinTable( property );
|
||||||
|
if ( joinTableAnn != null ) {
|
||||||
|
joinColumns = Ejb3JoinColumn.buildJoinColumns(
|
||||||
|
joinTableAnn.inverseJoinColumns(), null, entityBinder.getSecondaryTables(),
|
||||||
|
propertyHolder, inferredData.getPropertyName(), mappings
|
||||||
|
);
|
||||||
|
if ( StringHelper.isEmpty( joinTableAnn.name() ) ) {
|
||||||
|
throw new AnnotationException(
|
||||||
|
"JoinTable.name() on a @ToOne association has to be explicit: "
|
||||||
|
+ StringHelper.qualify( propertyHolder.getPath(), inferredData.getPropertyName() )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
OneToOne oneToOneAnn = property.getAnnotation( OneToOne.class );
|
||||||
|
String mappedBy = oneToOneAnn != null ?
|
||||||
|
oneToOneAnn.mappedBy() :
|
||||||
|
null;
|
||||||
|
joinColumns = Ejb3JoinColumn.buildJoinColumns(
|
||||||
|
( JoinColumn[]) null,
|
||||||
|
mappedBy, entityBinder.getSecondaryTables(),
|
||||||
|
propertyHolder, inferredData.getPropertyName(), mappings
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return joinColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Ejb3JoinColumn[] buildExplicitJoinColumns(PropertyHolder propertyHolder, XProperty property, PropertyData inferredData, EntityBinder entityBinder, ExtendedMappings mappings) {
|
||||||
|
//process @JoinColumn(s) before @Column(s) to handle collection of entities properly
|
||||||
|
Ejb3JoinColumn[] joinColumns = null;
|
||||||
|
{
|
||||||
|
JoinColumn[] anns = null;
|
||||||
|
|
||||||
|
if ( property.isAnnotationPresent( JoinColumn.class ) ) {
|
||||||
|
anns = new JoinColumn[] { property.getAnnotation( JoinColumn.class ) };
|
||||||
|
}
|
||||||
|
else if ( property.isAnnotationPresent( JoinColumns.class ) ) {
|
||||||
|
JoinColumns ann = property.getAnnotation( JoinColumns.class );
|
||||||
|
anns = ann.value();
|
||||||
|
int length = anns.length;
|
||||||
|
if ( length == 0 ) {
|
||||||
|
throw new AnnotationException( "Cannot bind an empty @JoinColumns" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( anns != null ) {
|
||||||
|
joinColumns = Ejb3JoinColumn.buildJoinColumns(
|
||||||
|
anns, null, entityBinder.getSecondaryTables(),
|
||||||
|
propertyHolder, inferredData.getPropertyName(), mappings
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if ( property.isAnnotationPresent( JoinColumnsOrFormulas.class ) ) {
|
||||||
|
JoinColumnsOrFormulas ann = property.getAnnotation( JoinColumnsOrFormulas.class );
|
||||||
|
joinColumns = Ejb3JoinColumn.buildJoinColumnsOrFormulas(
|
||||||
|
ann, null, entityBinder.getSecondaryTables(),
|
||||||
|
propertyHolder, inferredData.getPropertyName(), mappings
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return joinColumns;
|
||||||
|
}
|
||||||
|
|
||||||
//TODO move that to collection binder?
|
//TODO move that to collection binder?
|
||||||
private static void bindJoinedTableAssociation(
|
private static void bindJoinedTableAssociation(
|
||||||
XProperty property, ExtendedMappings mappings, EntityBinder entityBinder,
|
XProperty property, ExtendedMappings mappings, EntityBinder entityBinder,
|
||||||
|
@ -1979,6 +2002,7 @@ public final class AnnotationBinder {
|
||||||
inferredData, propertyHolder, mappings
|
inferredData, propertyHolder, mappings
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final XClass entityXClass = inferredData.getPropertyClass();
|
||||||
List<PropertyData> classElements = new ArrayList<PropertyData>();
|
List<PropertyData> classElements = new ArrayList<PropertyData>();
|
||||||
XClass returnedClassOrElement = inferredData.getClassOrElement();
|
XClass returnedClassOrElement = inferredData.getClassOrElement();
|
||||||
|
|
||||||
|
@ -1989,25 +2013,25 @@ public final class AnnotationBinder {
|
||||||
baseClassElements = new ArrayList<PropertyData>();
|
baseClassElements = new ArrayList<PropertyData>();
|
||||||
baseReturnedClassOrElement = baseInferredData.getClassOrElement();
|
baseReturnedClassOrElement = baseInferredData.getClassOrElement();
|
||||||
bindTypeDefs(baseReturnedClassOrElement, mappings);
|
bindTypeDefs(baseReturnedClassOrElement, mappings);
|
||||||
PropertyContainer propContainer = new PropertyContainer( baseReturnedClassOrElement );
|
PropertyContainer propContainer = new PropertyContainer( baseReturnedClassOrElement, entityXClass );
|
||||||
addElementsOfClass( baseClassElements, propertyAccessor, propContainer, mappings );
|
addElementsOfClass( baseClassElements, propertyAccessor, propContainer, mappings );
|
||||||
}
|
}
|
||||||
|
|
||||||
//embeddable elements can have type defs
|
//embeddable elements can have type defs
|
||||||
bindTypeDefs(returnedClassOrElement, mappings);
|
bindTypeDefs(returnedClassOrElement, mappings);
|
||||||
PropertyContainer propContainer = new PropertyContainer( returnedClassOrElement );
|
PropertyContainer propContainer = new PropertyContainer( returnedClassOrElement, entityXClass );
|
||||||
addElementsOfClass( classElements, propertyAccessor, propContainer, mappings);
|
addElementsOfClass( classElements, propertyAccessor, propContainer, mappings);
|
||||||
|
|
||||||
//add elements of the embeddable superclass
|
//add elements of the embeddable superclass
|
||||||
XClass superClass = inferredData.getPropertyClass().getSuperclass();
|
XClass superClass = entityXClass.getSuperclass();
|
||||||
while ( superClass != null && superClass.isAnnotationPresent( MappedSuperclass.class ) ) {
|
while ( superClass != null && superClass.isAnnotationPresent( MappedSuperclass.class ) ) {
|
||||||
//FIXME: proper support of typevariables incl var resolved at upper levels
|
//FIXME: proper support of typevariables incl var resolved at upper levels
|
||||||
propContainer = new PropertyContainer( superClass );
|
propContainer = new PropertyContainer( superClass, entityXClass );
|
||||||
addElementsOfClass( classElements, propertyAccessor, propContainer, mappings );
|
addElementsOfClass( classElements, propertyAccessor, propContainer, mappings );
|
||||||
superClass = superClass.getSuperclass();
|
superClass = superClass.getSuperclass();
|
||||||
}
|
}
|
||||||
if ( baseClassElements != null ) {
|
if ( baseClassElements != null ) {
|
||||||
if ( !hasIdClassAnnotations( inferredData.getPropertyClass() ) ) {
|
if ( !hasIdClassAnnotations( entityXClass ) ) {
|
||||||
for ( int i = 0; i < classElements.size(); i++ ) {
|
for ( int i = 0; i < classElements.size(); i++ ) {
|
||||||
classElements.set( i, baseClassElements.get( i ) ); //this works since they are in the same order
|
classElements.set( i, baseClassElements.get( i ) ); //this works since they are in the same order
|
||||||
}
|
}
|
||||||
|
@ -2082,6 +2106,22 @@ public final class AnnotationBinder {
|
||||||
setupComponentTuplizer( property, componentId );
|
setupComponentTuplizer( property, componentId );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
final XClass persistentXClass;
|
||||||
|
try {
|
||||||
|
persistentXClass = mappings.getReflectionManager()
|
||||||
|
.classForName( persistentClassName, AnnotationBinder.class );
|
||||||
|
}
|
||||||
|
catch ( ClassNotFoundException e ) {
|
||||||
|
throw new AssertionFailure( "Persistence class name cannot be converted into a Class", e);
|
||||||
|
}
|
||||||
|
final PropertyData annotatedWithMapsId = mappings.getPropertyAnnotatedWithMapsId( persistentXClass, "" );
|
||||||
|
if ( annotatedWithMapsId != null ) {
|
||||||
|
columns = buildExplicitJoinColumns( propertyHolder, annotatedWithMapsId.getProperty(), annotatedWithMapsId, entityBinder, mappings );
|
||||||
|
if (columns == null) {
|
||||||
|
columns = buildDefaultJoinColumnsForXToOne( propertyHolder, annotatedWithMapsId.getProperty(), annotatedWithMapsId, entityBinder, mappings );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (Ejb3Column column : columns) {
|
for (Ejb3Column column : columns) {
|
||||||
column.forceNotNull(); //this is an id
|
column.forceNotNull(); //this is an id
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,6 +46,7 @@ import java.util.StringTokenizer;
|
||||||
import javax.persistence.Embeddable;
|
import javax.persistence.Embeddable;
|
||||||
import javax.persistence.Entity;
|
import javax.persistence.Entity;
|
||||||
import javax.persistence.MappedSuperclass;
|
import javax.persistence.MappedSuperclass;
|
||||||
|
import javax.persistence.MapsId;
|
||||||
|
|
||||||
import org.dom4j.Attribute;
|
import org.dom4j.Attribute;
|
||||||
import org.dom4j.Document;
|
import org.dom4j.Document;
|
||||||
|
@ -64,6 +65,7 @@ import org.hibernate.DuplicateMappingException;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.Interceptor;
|
import org.hibernate.Interceptor;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.Session;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.annotations.AnyMetaDef;
|
import org.hibernate.annotations.AnyMetaDef;
|
||||||
import org.hibernate.annotations.common.reflection.MetadataProvider;
|
import org.hibernate.annotations.common.reflection.MetadataProvider;
|
||||||
|
@ -141,6 +143,7 @@ public class AnnotationConfiguration extends Configuration {
|
||||||
private transient ReflectionManager reflectionManager;
|
private transient ReflectionManager reflectionManager;
|
||||||
private boolean isDefaultProcessed = false;
|
private boolean isDefaultProcessed = false;
|
||||||
private boolean isValidatorNotPresentLogged;
|
private boolean isValidatorNotPresentLogged;
|
||||||
|
private Map<XClass,Map<String,PropertyData>> propertiesAnnotatedWithMapsId;
|
||||||
|
|
||||||
public AnnotationConfiguration() {
|
public AnnotationConfiguration() {
|
||||||
super();
|
super();
|
||||||
|
@ -279,6 +282,7 @@ public class AnnotationConfiguration extends Configuration {
|
||||||
namingStrategy = EJB3NamingStrategy.INSTANCE;
|
namingStrategy = EJB3NamingStrategy.INSTANCE;
|
||||||
setEntityResolver( new EJB3DTDEntityResolver() );
|
setEntityResolver( new EJB3DTDEntityResolver() );
|
||||||
anyMetaDefs = new HashMap<String, AnyMetaDef>();
|
anyMetaDefs = new HashMap<String, AnyMetaDef>();
|
||||||
|
propertiesAnnotatedWithMapsId = new HashMap<XClass, Map<String,PropertyData>>();
|
||||||
reflectionManager = new JavaReflectionManager();
|
reflectionManager = new JavaReflectionManager();
|
||||||
( ( MetadataProviderInjector ) reflectionManager ).setMetadataProvider( new JPAMetadataProvider() );
|
( ( MetadataProviderInjector ) reflectionManager ).setMetadataProvider( new JPAMetadataProvider() );
|
||||||
|
|
||||||
|
@ -1271,6 +1275,20 @@ public class AnnotationConfiguration extends Configuration {
|
||||||
return inSecondPass;
|
return inSecondPass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PropertyData getPropertyAnnotatedWithMapsId(XClass entityType, String propertyName) {
|
||||||
|
final Map<String, PropertyData> map = propertiesAnnotatedWithMapsId.get( entityType );
|
||||||
|
return map == null ? null : map.get( propertyName );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPropertyAnnotatedWithMapsId(XClass entityType, PropertyData property) {
|
||||||
|
Map<String, PropertyData> map = propertiesAnnotatedWithMapsId.get( entityType );
|
||||||
|
if (map == null) {
|
||||||
|
map = new HashMap<String, PropertyData>();
|
||||||
|
propertiesAnnotatedWithMapsId.put( entityType, map );
|
||||||
|
}
|
||||||
|
map.put( property.getProperty().getAnnotation( MapsId.class ).value(), property );
|
||||||
|
}
|
||||||
|
|
||||||
public IdGenerator getGenerator(String name) {
|
public IdGenerator getGenerator(String name) {
|
||||||
return getGenerator( name, null );
|
return getGenerator( name, null );
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,4 +171,12 @@ public interface ExtendedMappings extends Mappings {
|
||||||
public AnyMetaDef getAnyMetaDef(String name);
|
public AnyMetaDef getAnyMetaDef(String name);
|
||||||
|
|
||||||
public boolean isInSecondPass();
|
public boolean isInSecondPass();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the property annotated with @MapsId("propertyName") if any.
|
||||||
|
* Null otherwise
|
||||||
|
*/
|
||||||
|
public PropertyData getPropertyAnnotatedWithMapsId(XClass entityType, String propertyName);
|
||||||
|
|
||||||
|
public void addPropertyAnnotatedWithMapsId(XClass entityType, PropertyData property);
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
// $Id:$
|
// $Id$
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
|
@ -55,20 +55,26 @@ import org.hibernate.util.StringHelper;
|
||||||
class PropertyContainer {
|
class PropertyContainer {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
|
private static final Logger log = LoggerFactory.getLogger( AnnotationBinder.class );
|
||||||
|
private final XClass entityAtStake;
|
||||||
private final TreeMap<String, XProperty> fieldAccessMap;
|
private final TreeMap<String, XProperty> fieldAccessMap;
|
||||||
private final TreeMap<String, XProperty> propertyAccessMap;
|
private final TreeMap<String, XProperty> propertyAccessMap;
|
||||||
private final XClass xClass;
|
private final XClass xClass;
|
||||||
private final AccessType explicitClassDefinedAccessType;
|
private final AccessType explicitClassDefinedAccessType;
|
||||||
|
|
||||||
PropertyContainer(XClass clazz) {
|
PropertyContainer(XClass clazz, XClass entityAtStake) {
|
||||||
this.xClass = clazz;
|
this.xClass = clazz;
|
||||||
|
this.entityAtStake = entityAtStake;
|
||||||
fieldAccessMap = initProperties( AccessType.FIELD );
|
fieldAccessMap = initProperties( AccessType.FIELD );
|
||||||
propertyAccessMap = initProperties( AccessType.PROPERTY );
|
propertyAccessMap = initProperties( AccessType.PROPERTY );
|
||||||
explicitClassDefinedAccessType = determineClassDefinedAccessStrategy();
|
explicitClassDefinedAccessType = determineClassDefinedAccessStrategy();
|
||||||
checkForJpaAccess();
|
checkForJpaAccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
public XClass getXClass() {
|
public XClass getEntityAtStake() {
|
||||||
|
return entityAtStake;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XClass getDeclaringClass() {
|
||||||
return xClass;
|
return xClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
package org.hibernate.test.annotations.derivedidentities.e4.a;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.test.annotations.TestCase;
|
||||||
|
import org.hibernate.test.annotations.derivedidentities.e1.b.Dependent;
|
||||||
|
import org.hibernate.test.annotations.derivedidentities.e1.b.DependentId;
|
||||||
|
import org.hibernate.test.annotations.derivedidentities.e1.b.Employee;
|
||||||
|
import org.hibernate.test.util.SchemaUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
*/
|
||||||
|
public class DerivedIdentitySimpleParentSimpleDepTest extends TestCase {
|
||||||
|
|
||||||
|
public void testIt() 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;
|
||||||
|
d.id = "aaa"; //FIXME not needed when foreign is enabled
|
||||||
|
s.persist( d );
|
||||||
|
s.flush();
|
||||||
|
s.clear();
|
||||||
|
d = (MedicalHistory) s.get( MedicalHistory.class, d.id );
|
||||||
|
assertEquals( d.id, d.patient.ssn );
|
||||||
|
s.getTransaction().rollback();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getMappings() {
|
||||||
|
return new Class<?>[] {
|
||||||
|
MedicalHistory.class,
|
||||||
|
Person.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
package org.hibernate.test.annotations.derivedidentities.e4.a;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.JoinColumn;
|
||||||
|
import javax.persistence.MapsId;
|
||||||
|
import javax.persistence.OneToOne;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class MedicalHistory {
|
||||||
|
@Id
|
||||||
|
String id; // overriding not allowed ... // default join column name is overridden @MapsId
|
||||||
|
@JoinColumn(name = "FK")
|
||||||
|
@MapsId
|
||||||
|
@OneToOne
|
||||||
|
Person patient;
|
||||||
|
}
|
|
@ -0,0 +1,13 @@
|
||||||
|
package org.hibernate.test.annotations.derivedidentities.e4.a;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Emmanuel Bernard
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
public class Person {
|
||||||
|
@Id
|
||||||
|
String ssn;
|
||||||
|
}
|
Loading…
Reference in New Issue