mirror of
https://github.com/hibernate/hibernate-orm
synced 2025-02-17 16:44:57 +00:00
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 :) ) git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18619 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
671d9db8e2
commit
d00f7efb30
@ -625,10 +625,10 @@ else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) )
|
|||||||
HashMap<String, IdGenerator> classGenerators = buildLocalGenerators( clazzToProcess, mappings );
|
HashMap<String, IdGenerator> classGenerators = buildLocalGenerators( clazzToProcess, mappings );
|
||||||
|
|
||||||
// check properties
|
// check properties
|
||||||
List<PropertyData> elements =
|
final ElementsToProcess elementsToProcess = getElementsToProcess(
|
||||||
getElementsToProcess(
|
persistentClass, clazzToProcess, inheritanceStatePerClass, entityBinder, mappings
|
||||||
persistentClass, clazzToProcess, inheritanceStatePerClass, entityBinder, mappings
|
);
|
||||||
);
|
|
||||||
final boolean subclassAndSingleTableStrategy = inheritanceState.getType() == InheritanceType.SINGLE_TABLE
|
final boolean subclassAndSingleTableStrategy = inheritanceState.getType() == InheritanceType.SINGLE_TABLE
|
||||||
&& inheritanceState.hasParents();
|
&& inheritanceState.hasParents();
|
||||||
//process idclass if any
|
//process idclass if any
|
||||||
@ -674,7 +674,9 @@ else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) )
|
|||||||
isComponent,
|
isComponent,
|
||||||
propertyAccessor, entityBinder,
|
propertyAccessor, entityBinder,
|
||||||
true,
|
true,
|
||||||
false, mappings, inheritanceStatePerClass
|
false,
|
||||||
|
mappings,
|
||||||
|
inheritanceStatePerClass
|
||||||
);
|
);
|
||||||
inferredData = new PropertyPreloadedData(
|
inferredData = new PropertyPreloadedData(
|
||||||
propertyAccessor, "_identifierMapper", compositeClass
|
propertyAccessor, "_identifierMapper", compositeClass
|
||||||
@ -683,9 +685,11 @@ else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) )
|
|||||||
propertyHolder,
|
propertyHolder,
|
||||||
inferredData,
|
inferredData,
|
||||||
baseInferredData,
|
baseInferredData,
|
||||||
propertyAccessor, false,
|
propertyAccessor,
|
||||||
|
false,
|
||||||
entityBinder,
|
entityBinder,
|
||||||
true, true,
|
true,
|
||||||
|
true,
|
||||||
false, mappings, inheritanceStatePerClass
|
false, mappings, inheritanceStatePerClass
|
||||||
);
|
);
|
||||||
entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
|
entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
|
||||||
@ -720,8 +724,11 @@ else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) )
|
|||||||
idProperties.add( ( (Property) properties.next() ).getName() );
|
idProperties.add( ( (Property) properties.next() ).getName() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
entityBinder.setWrapIdsInEmbeddedComponents( elementsToProcess.getIdPropertyCount() > 1 );
|
||||||
|
}
|
||||||
Set<String> missingIdProperties = new HashSet<String>( idProperties );
|
Set<String> missingIdProperties = new HashSet<String>( idProperties );
|
||||||
for (PropertyData propertyAnnotatedElement : elements) {
|
for (PropertyData propertyAnnotatedElement : elementsToProcess.getElements() ) {
|
||||||
String propertyName = propertyAnnotatedElement.getPropertyName();
|
String propertyName = propertyAnnotatedElement.getPropertyName();
|
||||||
if ( !idProperties.contains( propertyName ) ) {
|
if ( !idProperties.contains( propertyName ) ) {
|
||||||
processElementAnnotations(
|
processElementAnnotations(
|
||||||
@ -979,7 +986,7 @@ private static boolean isEntityClassType(XClass clazzToProcess, AnnotatedClassTy
|
|||||||
* Get the annotated elements, guessing the access type from @Id or @EmbeddedId presence.
|
* Get the annotated elements, guessing the access type from @Id or @EmbeddedId presence.
|
||||||
* Change EntityBinder by side effect
|
* Change EntityBinder by side effect
|
||||||
*/
|
*/
|
||||||
private static List<PropertyData> getElementsToProcess(
|
private static ElementsToProcess getElementsToProcess(
|
||||||
PersistentClass persistentClass, XClass clazzToProcess,
|
PersistentClass persistentClass, XClass clazzToProcess,
|
||||||
Map<XClass, InheritanceState> inheritanceStatePerClass,
|
Map<XClass, InheritanceState> inheritanceStatePerClass,
|
||||||
EntityBinder entityBinder, ExtendedMappings mappings
|
EntityBinder entityBinder, ExtendedMappings mappings
|
||||||
@ -996,21 +1003,39 @@ private static List<PropertyData> getElementsToProcess(
|
|||||||
|
|
||||||
List<PropertyData> elements = new ArrayList<PropertyData>();
|
List<PropertyData> elements = new ArrayList<PropertyData>();
|
||||||
int deep = classesToProcess.size();
|
int deep = classesToProcess.size();
|
||||||
boolean hasIdentifier = false;
|
int idPropertyCount = 0;
|
||||||
|
|
||||||
for ( int index = 0; index < deep; index++ ) {
|
for ( int index = 0; index < deep; index++ ) {
|
||||||
PropertyContainer properyContainer = new PropertyContainer( classesToProcess.get( index ), clazzToProcess );
|
PropertyContainer propertyContainer = new PropertyContainer( classesToProcess.get( index ), clazzToProcess );
|
||||||
boolean currentHasIdentifier = addElementsOfClass( elements, accessType, properyContainer, mappings );
|
int currentIdPropertyCount = addElementsOfClass( elements, accessType, propertyContainer, mappings );
|
||||||
hasIdentifier = hasIdentifier || currentHasIdentifier;
|
idPropertyCount += currentIdPropertyCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
entityBinder.setPropertyAccessType( accessType );
|
entityBinder.setPropertyAccessType( accessType );
|
||||||
|
|
||||||
if ( !hasIdentifier && !inheritanceState.hasParents() ) {
|
if ( idPropertyCount == 0 && !inheritanceState.hasParents() ) {
|
||||||
throw new AnnotationException( "No identifier specified for entity: " + clazzToProcess.getName() );
|
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) {
|
private static AccessType determineDefaultAccessType(XClass annotatedClass, Map<XClass, InheritanceState> inheritanceStatePerClass) {
|
||||||
@ -1207,13 +1232,13 @@ private static void bindDiscriminatorToPersistentClass(
|
|||||||
* strategy is used
|
* strategy is used
|
||||||
* @param propertyContainer Metadata about a class and its properties
|
* @param propertyContainer Metadata about a class and its properties
|
||||||
* @param mappings Mapping meta data
|
* @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.
|
* the determined access strategy, {@code false} otherwise.
|
||||||
*/
|
*/
|
||||||
private static boolean addElementsOfClass(
|
private static int addElementsOfClass(
|
||||||
List<PropertyData> elements, AccessType defaultAccessType, PropertyContainer propertyContainer, ExtendedMappings mappings
|
List<PropertyData> elements, AccessType defaultAccessType, PropertyContainer propertyContainer, ExtendedMappings mappings
|
||||||
) {
|
) {
|
||||||
boolean hasIdentifier = false;
|
int idPropertyCounter = 0;
|
||||||
AccessType accessType = defaultAccessType;
|
AccessType accessType = defaultAccessType;
|
||||||
|
|
||||||
if ( propertyContainer.hasExplicitAccessStrategy() ) {
|
if ( propertyContainer.hasExplicitAccessStrategy() ) {
|
||||||
@ -1223,21 +1248,21 @@ private static boolean addElementsOfClass(
|
|||||||
propertyContainer.assertTypesAreResolvable( accessType );
|
propertyContainer.assertTypesAreResolvable( accessType );
|
||||||
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 int currentIdPropertyCounter = addProperty(
|
||||||
propertyContainer, p, elements, accessType.getType(), mappings
|
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,
|
PropertyContainer propertyContainer, XProperty property, List<PropertyData> annElts,
|
||||||
String propertyAccessor, ExtendedMappings mappings
|
String propertyAccessor, ExtendedMappings mappings
|
||||||
) {
|
) {
|
||||||
final XClass declaringClass = propertyContainer.getDeclaringClass();
|
final XClass declaringClass = propertyContainer.getDeclaringClass();
|
||||||
final XClass entity = propertyContainer.getEntityAtStake();
|
final XClass entity = propertyContainer.getEntityAtStake();
|
||||||
boolean hasIdentifier;
|
int idPropertyCounter = 0;
|
||||||
PropertyData propertyAnnotatedElement = new PropertyInferredData(
|
PropertyData propertyAnnotatedElement = new PropertyInferredData(
|
||||||
declaringClass, property, propertyAccessor,
|
declaringClass, property, propertyAccessor,
|
||||||
mappings.getReflectionManager() );
|
mappings.getReflectionManager() );
|
||||||
@ -1249,17 +1274,16 @@ private static boolean addProperty(
|
|||||||
final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
|
final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
|
||||||
if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent( EmbeddedId.class ) ) {
|
if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent( EmbeddedId.class ) ) {
|
||||||
annElts.add( 0, propertyAnnotatedElement );
|
annElts.add( 0, propertyAnnotatedElement );
|
||||||
hasIdentifier = true;
|
idPropertyCounter++;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
annElts.add( propertyAnnotatedElement );
|
annElts.add( propertyAnnotatedElement );
|
||||||
hasIdentifier = false;
|
|
||||||
}
|
}
|
||||||
if ( element.isAnnotationPresent( MapsId.class ) ) {
|
if ( element.isAnnotationPresent( MapsId.class ) ) {
|
||||||
mappings.addPropertyAnnotatedWithMapsId( entity, propertyAnnotatedElement );
|
mappings.addPropertyAnnotatedWithMapsId( entity, propertyAnnotatedElement );
|
||||||
}
|
}
|
||||||
|
|
||||||
return hasIdentifier;
|
return idPropertyCounter;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1361,9 +1385,28 @@ else if ( joinColumns == null && property.isAnnotationPresent( org.hibernate.ann
|
|||||||
|
|
||||||
final XClass returnedClass = inferredData.getClassOrElement();
|
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() &&
|
boolean isId = !entityBinder.isIgnoreIdAnnotations() &&
|
||||||
( property.isAnnotationPresent( Id.class )
|
( property.isAnnotationPresent( Id.class )
|
||||||
|| property.isAnnotationPresent( EmbeddedId.class ) );
|
|| property.isAnnotationPresent( EmbeddedId.class ) );
|
||||||
|
propertyBinder.setId( isId );
|
||||||
|
|
||||||
if ( property.isAnnotationPresent( Version.class ) ) {
|
if ( property.isAnnotationPresent( Version.class ) ) {
|
||||||
if ( isIdentifierMapper ) {
|
if ( isIdentifierMapper ) {
|
||||||
throw new AnnotationException(
|
throw new AnnotationException(
|
||||||
@ -1384,19 +1427,14 @@ else if ( joinColumns == null && property.isAnnotationPresent( org.hibernate.ann
|
|||||||
}
|
}
|
||||||
log.trace( "{} is a version property", inferredData.getPropertyName() );
|
log.trace( "{} is a version property", inferredData.getPropertyName() );
|
||||||
RootClass rootClass = (RootClass) propertyHolder.getPersistentClass();
|
RootClass rootClass = (RootClass) propertyHolder.getPersistentClass();
|
||||||
PropertyBinder propBinder = new PropertyBinder();
|
// PropertyBinder propBinder = new PropertyBinder();
|
||||||
propBinder.setName( inferredData.getPropertyName() );
|
// propBinder.setName( inferredData.getPropertyName() );
|
||||||
propBinder.setReturnedClassName( inferredData.getTypeName() );
|
// propBinder.setReturnedClassName( inferredData.getTypeName() );
|
||||||
propBinder.setLazy( false );
|
// propBinder.setLazy( false );
|
||||||
propBinder.setAccessType( inferredData.getDefaultAccess() );
|
// propBinder.setAccessType( inferredData.getDefaultAccess() );
|
||||||
propBinder.setColumns( columns );
|
propertyBinder.setColumns( columns );
|
||||||
propBinder.setHolder( propertyHolder ); //PropertyHolderBuilder.buildPropertyHolder(rootClass)
|
Property prop = propertyBinder.makePropertyValueAndBind();
|
||||||
propBinder.setProperty( property );
|
propertyBinder.getSimpleValueBinder().setVersion(true);
|
||||||
propBinder.setReturnedClass( inferredData.getPropertyClass() );
|
|
||||||
propBinder.setMappings( mappings );
|
|
||||||
propBinder.setDeclaringClass( inferredData.getDeclaringClass() );
|
|
||||||
Property prop = propBinder.makePropertyValueAndBind();
|
|
||||||
propBinder.getSimpleValueBinder().setVersion(true);
|
|
||||||
rootClass.setVersion( prop );
|
rootClass.setVersion( prop );
|
||||||
|
|
||||||
//If version is on a mapped superclass, update the mapping
|
//If version is on a mapped superclass, update the mapping
|
||||||
@ -1451,7 +1489,8 @@ else if ( property.isAnnotationPresent( ManyToOne.class ) ) {
|
|||||||
ignoreNotFound, onDeleteCascade,
|
ignoreNotFound, onDeleteCascade,
|
||||||
ToOneBinder.getTargetEntity( inferredData, mappings ),
|
ToOneBinder.getTargetEntity( inferredData, mappings ),
|
||||||
propertyHolder,
|
propertyHolder,
|
||||||
inferredData, false, isIdentifierMapper, inSecondPass, mappings
|
inferredData, false, isIdentifierMapper,
|
||||||
|
inSecondPass, propertyBinder, mappings
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if ( property.isAnnotationPresent( OneToOne.class ) ) {
|
else if ( property.isAnnotationPresent( OneToOne.class ) ) {
|
||||||
@ -1489,7 +1528,13 @@ else if ( property.isAnnotationPresent( OneToOne.class ) ) {
|
|||||||
ignoreNotFound, onDeleteCascade,
|
ignoreNotFound, onDeleteCascade,
|
||||||
ToOneBinder.getTargetEntity( inferredData, mappings ),
|
ToOneBinder.getTargetEntity( inferredData, mappings ),
|
||||||
propertyHolder,
|
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 ) ) {
|
else if ( property.isAnnotationPresent( org.hibernate.annotations.Any.class ) ) {
|
||||||
@ -1793,7 +1838,7 @@ else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) {
|
|||||||
isComponent = property.isAnnotationPresent( Embedded.class )
|
isComponent = property.isAnnotationPresent( Embedded.class )
|
||||||
|| property.isAnnotationPresent( EmbeddedId.class )
|
|| property.isAnnotationPresent( EmbeddedId.class )
|
||||||
|| returnedClass.isAnnotationPresent( Embeddable.class );
|
|| returnedClass.isAnnotationPresent( Embeddable.class );
|
||||||
PropertyBinder propertyBinder;
|
|
||||||
if ( isComponent ) {
|
if ( isComponent ) {
|
||||||
AccessType propertyAccessor = entityBinder.getPropertyAccessor( property );
|
AccessType propertyAccessor = entityBinder.getPropertyAccessor( property );
|
||||||
propertyBinder = bindComponent(
|
propertyBinder = bindComponent(
|
||||||
@ -1835,23 +1880,12 @@ else if ( !isId || !entityBinder.isIgnoreIdAnnotations() ) {
|
|||||||
mappings );
|
mappings );
|
||||||
}
|
}
|
||||||
|
|
||||||
propertyBinder = new PropertyBinder();
|
|
||||||
propertyBinder.setName( inferredData.getPropertyName() );
|
|
||||||
propertyBinder.setReturnedClassName( inferredData.getTypeName() );
|
|
||||||
propertyBinder.setLazy( lazy );
|
propertyBinder.setLazy( lazy );
|
||||||
propertyBinder.setAccessType( inferredData.getDefaultAccess() );
|
|
||||||
propertyBinder.setColumns( columns );
|
propertyBinder.setColumns( columns );
|
||||||
propertyBinder.setHolder( propertyHolder );
|
// if ( isIdentifierMapper ) {
|
||||||
propertyBinder.setProperty( property );
|
// propertyBinder.setInsertable( false );
|
||||||
propertyBinder.setReturnedClass( inferredData.getPropertyClass() );
|
// propertyBinder.setUpdatable( false );
|
||||||
propertyBinder.setMappings( mappings );
|
// }
|
||||||
if ( isIdentifierMapper ) {
|
|
||||||
propertyBinder.setInsertable( false );
|
|
||||||
propertyBinder.setUpdatable( false );
|
|
||||||
}
|
|
||||||
propertyBinder.setDeclaringClass( inferredData.getDeclaringClass() );
|
|
||||||
propertyBinder.setId(isId);
|
|
||||||
propertyBinder.setInheritanceStatePerClass(inheritanceStatePerClass);
|
|
||||||
propertyBinder.makePropertyValueAndBind();
|
propertyBinder.makePropertyValueAndBind();
|
||||||
}
|
}
|
||||||
if (isId) {
|
if (isId) {
|
||||||
@ -2105,6 +2139,7 @@ private static PropertyBinder bindComponent(
|
|||||||
binder.setEmbedded( isComponentEmbedded );
|
binder.setEmbedded( isComponentEmbedded );
|
||||||
binder.setHolder( propertyHolder );
|
binder.setHolder( propertyHolder );
|
||||||
binder.setId( isId );
|
binder.setId( isId );
|
||||||
|
binder.setEntityBinder( entityBinder );
|
||||||
binder.setInheritanceStatePerClass( inheritanceStatePerClass );
|
binder.setInheritanceStatePerClass( inheritanceStatePerClass );
|
||||||
binder.setMappings( mappings );
|
binder.setMappings( mappings );
|
||||||
binder.makePropertyAndBind();
|
binder.makePropertyAndBind();
|
||||||
@ -2136,17 +2171,7 @@ public static Component fillComponent(
|
|||||||
* Because it's a value type, there is no bidirectional association, hence second pass
|
* Because it's a value type, there is no bidirectional association, hence second pass
|
||||||
* ordering does not matter
|
* ordering does not matter
|
||||||
*/
|
*/
|
||||||
Component comp = new Component( propertyHolder.getPersistentClass() );
|
Component comp = createComponent( propertyHolder, inferredData, isComponentEmbedded, isIdentifierMapper );
|
||||||
comp.setEmbedded( isComponentEmbedded );
|
|
||||||
//yuk
|
|
||||||
comp.setTable( propertyHolder.getTable() );
|
|
||||||
if ( !isIdentifierMapper ) {
|
|
||||||
comp.setComponentClassName( inferredData.getClassOrElementName() );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
comp.setComponentClassName( comp.getOwner().getClassName() );
|
|
||||||
}
|
|
||||||
comp.setNodeName( inferredData.getPropertyName() );
|
|
||||||
String subpath = BinderHelper.getPath( propertyHolder, inferredData );
|
String subpath = BinderHelper.getPath( propertyHolder, inferredData );
|
||||||
log.trace( "Binding component with path: {}", subpath );
|
log.trace( "Binding component with path: {}", subpath );
|
||||||
PropertyHolder subHolder = PropertyHolderBuilder.buildPropertyHolder(
|
PropertyHolder subHolder = PropertyHolderBuilder.buildPropertyHolder(
|
||||||
@ -2202,6 +2227,22 @@ public static Component fillComponent(
|
|||||||
return comp;
|
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(
|
private static void bindId(
|
||||||
String generatorType, String generatorName,
|
String generatorType, String generatorName,
|
||||||
PropertyData inferredData, Ejb3Column[] columns, PropertyHolder propertyHolder,
|
PropertyData inferredData, Ejb3Column[] columns, PropertyHolder propertyHolder,
|
||||||
@ -2345,7 +2386,9 @@ private static void bindManyToOne(
|
|||||||
String cascadeStrategy, Ejb3JoinColumn[] columns, boolean optional,
|
String cascadeStrategy, Ejb3JoinColumn[] columns, boolean optional,
|
||||||
boolean ignoreNotFound, boolean cascadeOnDelete,
|
boolean ignoreNotFound, boolean cascadeOnDelete,
|
||||||
XClass targetEntity, PropertyHolder propertyHolder,
|
XClass targetEntity, PropertyHolder propertyHolder,
|
||||||
PropertyData inferredData, boolean unique, boolean isIdentifierMapper, boolean inSecondPass,
|
PropertyData inferredData, boolean unique,
|
||||||
|
boolean isIdentifierMapper, boolean inSecondPass,
|
||||||
|
PropertyBinder propertyBinder,
|
||||||
ExtendedMappings mappings
|
ExtendedMappings mappings
|
||||||
) {
|
) {
|
||||||
//All FK columns should be in the same table
|
//All FK columns should be in the same table
|
||||||
@ -2399,24 +2442,26 @@ private static void bindManyToOne(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ejb3Column.checkPropertyConsistency( columns, propertyHolder.getEntityName() + propertyName );
|
Ejb3Column.checkPropertyConsistency( columns, propertyHolder.getEntityName() + propertyName );
|
||||||
PropertyBinder binder = new PropertyBinder();
|
//PropertyBinder binder = new PropertyBinder();
|
||||||
binder.setName( propertyName );
|
propertyBinder.setName( propertyName );
|
||||||
binder.setValue( value );
|
propertyBinder.setValue( value );
|
||||||
//binder.setCascade(cascadeStrategy);
|
//binder.setCascade(cascadeStrategy);
|
||||||
if ( isIdentifierMapper ) {
|
if ( isIdentifierMapper ) {
|
||||||
binder.setInsertable( false );
|
propertyBinder.setInsertable( false );
|
||||||
binder.setUpdatable( false );
|
propertyBinder.setUpdatable( false );
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
binder.setInsertable( columns[0].isInsertable() );
|
propertyBinder.setInsertable( columns[0].isInsertable() );
|
||||||
binder.setUpdatable( columns[0].isUpdatable() );
|
propertyBinder.setUpdatable( columns[0].isUpdatable() );
|
||||||
}
|
}
|
||||||
binder.setAccessType( inferredData.getDefaultAccess() );
|
propertyBinder.setColumns( columns );
|
||||||
binder.setCascade( cascadeStrategy );
|
propertyBinder.setAccessType( inferredData.getDefaultAccess() );
|
||||||
binder.setProperty( property );
|
propertyBinder.setCascade( cascadeStrategy );
|
||||||
Property prop = binder.makeProperty();
|
propertyBinder.setProperty( property );
|
||||||
|
propertyBinder.setXToMany( true );
|
||||||
|
Property prop = propertyBinder.makePropertyAndBind();
|
||||||
//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() );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void defineFetchingStrategy(ToOne toOne, XProperty property) {
|
protected static void defineFetchingStrategy(ToOne toOne, XProperty property) {
|
||||||
@ -2476,7 +2521,10 @@ private static void bindOneToOne(
|
|||||||
PropertyHolder propertyHolder,
|
PropertyHolder propertyHolder,
|
||||||
PropertyData inferredData, String mappedBy,
|
PropertyData inferredData, String mappedBy,
|
||||||
boolean trueOneToOne,
|
boolean trueOneToOne,
|
||||||
boolean isIdentifierMapper, boolean inSecondPass, ExtendedMappings mappings
|
boolean isIdentifierMapper,
|
||||||
|
boolean inSecondPass,
|
||||||
|
PropertyBinder propertyBinder,
|
||||||
|
ExtendedMappings mappings
|
||||||
) {
|
) {
|
||||||
//column.getTable() => persistentClass.getTable()
|
//column.getTable() => persistentClass.getTable()
|
||||||
final String propertyName = inferredData.getPropertyName();
|
final String propertyName = inferredData.getPropertyName();
|
||||||
@ -2535,7 +2583,8 @@ private static void bindOneToOne(
|
|||||||
bindManyToOne(
|
bindManyToOne(
|
||||||
cascadeStrategy, joinColumns, optional, ignoreNotFound, cascadeOnDelete,
|
cascadeStrategy, joinColumns, optional, ignoreNotFound, cascadeOnDelete,
|
||||||
targetEntity,
|
targetEntity,
|
||||||
propertyHolder, inferredData, true, isIdentifierMapper, inSecondPass, mappings
|
propertyHolder, inferredData, true, isIdentifierMapper, inSecondPass,
|
||||||
|
propertyBinder, mappings
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,6 +119,11 @@ public class EntityBinder {
|
|||||||
private boolean ignoreIdAnnotations;
|
private boolean ignoreIdAnnotations;
|
||||||
private boolean cacheLazyProperty;
|
private boolean cacheLazyProperty;
|
||||||
private AccessType propertyAccessType = AccessType.DEFAULT;
|
private AccessType propertyAccessType = AccessType.DEFAULT;
|
||||||
|
private boolean wrapIdsInEmbeddedComponents;
|
||||||
|
|
||||||
|
public boolean wrapIdsInEmbeddedComponents() {
|
||||||
|
return wrapIdsInEmbeddedComponents;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use as a fake one for Collection of elements
|
* Use as a fake one for Collection of elements
|
||||||
@ -413,6 +418,11 @@ public void setWhere(Where whereAnn) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setWrapIdsInEmbeddedComponents(boolean wrapIdsInEmbeddedComponents) {
|
||||||
|
this.wrapIdsInEmbeddedComponents = wrapIdsInEmbeddedComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static class EntityTableObjectNameSource implements ObjectNameSource {
|
private static class EntityTableObjectNameSource implements ObjectNameSource {
|
||||||
private final String explicitName;
|
private final String explicitName;
|
||||||
private final String logicalName;
|
private final String logicalName;
|
||||||
|
@ -40,11 +40,14 @@
|
|||||||
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.cfg.AccessType;
|
import org.hibernate.cfg.AccessType;
|
||||||
|
import org.hibernate.cfg.AnnotationBinder;
|
||||||
import org.hibernate.cfg.BinderHelper;
|
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.InheritanceState;
|
||||||
import org.hibernate.cfg.PropertyHolder;
|
import org.hibernate.cfg.PropertyHolder;
|
||||||
|
import org.hibernate.cfg.PropertyPreloadedData;
|
||||||
|
import org.hibernate.mapping.Component;
|
||||||
import org.hibernate.mapping.KeyValue;
|
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;
|
||||||
@ -73,15 +76,21 @@ public class PropertyBinder {
|
|||||||
private XClass declaringClass;
|
private XClass declaringClass;
|
||||||
private boolean declaringClassSet;
|
private boolean declaringClassSet;
|
||||||
private boolean embedded;
|
private boolean embedded;
|
||||||
|
private EntityBinder entityBinder;
|
||||||
|
private boolean isXToMany;
|
||||||
|
|
||||||
public void setEmbedded(boolean embedded) {
|
public void setEmbedded(boolean embedded) {
|
||||||
this.embedded = embedded;
|
this.embedded = embedded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setEntityBinder(EntityBinder entityBinder) {
|
||||||
|
this.entityBinder = entityBinder;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* property can be null
|
* property can be null
|
||||||
* prefer propertyName to property.getName() since some are overloaded
|
* prefer propertyName to property.getName() since some are overloaded
|
||||||
*/
|
*/
|
||||||
private XProperty property;
|
private XProperty property;
|
||||||
private XClass returnedClass;
|
private XClass returnedClass;
|
||||||
private boolean isId;
|
private boolean isId;
|
||||||
@ -185,27 +194,45 @@ public Property makePropertyValueAndBind() {
|
|||||||
return bind( makePropertyAndValue() );
|
return bind( makePropertyAndValue() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setXToMany(boolean xToMany) {
|
||||||
|
this.isXToMany = xToMany;
|
||||||
|
}
|
||||||
|
|
||||||
private Property bind(Property prop) {
|
private Property bind(Property prop) {
|
||||||
if (isId) {
|
if (isId) {
|
||||||
final RootClass rootClass = ( RootClass ) holder.getPersistentClass();
|
final RootClass rootClass = ( RootClass ) holder.getPersistentClass();
|
||||||
rootClass.setIdentifier( ( KeyValue ) getValue() );
|
//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 (embedded) {
|
if ( isXToMany || entityBinder.wrapIdsInEmbeddedComponents() ) {
|
||||||
rootClass.setEmbeddedIdentifier( true );
|
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 {
|
else {
|
||||||
rootClass.setIdentifierProperty( prop );
|
rootClass.setIdentifier( ( KeyValue ) getValue() );
|
||||||
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
|
if (embedded) {
|
||||||
declaringClass,
|
rootClass.setEmbeddedIdentifier( true );
|
||||||
inheritanceStatePerClass,
|
|
||||||
mappings
|
|
||||||
);
|
|
||||||
if (superclass != null) {
|
|
||||||
superclass.setDeclaredIdentifierProperty(prop);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//we know the property is on the actual entity
|
rootClass.setIdentifierProperty( prop );
|
||||||
rootClass.setDeclaredIdentifierProperty( 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 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// $Id:$
|
// $Id$
|
||||||
/*
|
/*
|
||||||
* Hibernate, Relational Persistence for Idiomatic Java
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
*
|
*
|
||||||
@ -24,6 +24,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.hibernate.cfg.annotations;
|
package org.hibernate.cfg.annotations;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -34,7 +36,7 @@ public class Version {
|
|||||||
private static Logger log = LoggerFactory.getLogger( Version.class );
|
private static Logger log = LoggerFactory.getLogger( Version.class );
|
||||||
|
|
||||||
public static String getVersionString() {
|
public static String getVersionString() {
|
||||||
return "[WORKING]";
|
return "[WORKING]-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
@ -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;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user