Author: epbernard
Date: 2009-10-28 14:14:25 -0400 (Wed, 28 Oct 2009)
New Revision: 17871
Added:
core/trunk/core/src/main/java/org/hibernate/mapping/MappedSuperclass.java
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyData.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ListBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
core/trunk/core/src/main/java/org/hibernate/mapping/Join.java
core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java
core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java
Log:
HHH-4533 add representation for @MappedSuperclass in the Hibernate Core metamodel and
properly populate this model extension in Hibernate Annotations
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -66,6 +66,10 @@
return path;
}
+ protected ExtendedMappings getMappings() {
+ return mappings;
+ }
+
/**
* property can be null
*/
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -457,9 +457,10 @@
}
XAnnotatedElement annotatedClass = clazzToProcess;
log.info( "Binding entity from annotated class: {}", clazzToProcess.getName()
);
+ final ReflectionManager reflectionManager = mappings.getReflectionManager();
InheritanceState superEntityState =
InheritanceState.getSuperEntityInheritanceState(
- clazzToProcess, inheritanceStatePerClass, mappings.getReflectionManager()
+ clazzToProcess, inheritanceStatePerClass, reflectionManager
);
PersistentClass superEntity = superEntityState != null ?
mappings.getClass(
@@ -627,7 +628,7 @@
PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder(
clazzToProcess,
persistentClass,
- entityBinder, mappings
+ entityBinder, mappings, inheritanceStatePerClass
);
javax.persistence.SecondaryTable secTabAnn = annotatedClass.getAnnotation(
@@ -702,7 +703,7 @@
// check properties
List<PropertyData> elements =
getElementsToProcess(
- clazzToProcess, inheritanceStatePerClass, propertyHolder, entityBinder, mappings
+ persistentClass, clazzToProcess, inheritanceStatePerClass, propertyHolder,
entityBinder, mappings
);
if ( elements == null ) {
throw new AnnotationException( "No identifier specified for entity: " +
propertyHolder.getEntityName() );
@@ -724,13 +725,13 @@
break;
}
state = InheritanceState.getSuperclassInheritanceState(
- current, inheritanceStatePerClass, mappings.getReflectionManager()
+ current, inheritanceStatePerClass, reflectionManager
);
}
while ( state != null );
}
if ( idClass != null ) {
- XClass compositeClass = mappings.getReflectionManager().toXClass( idClass.value() );
+ XClass compositeClass = reflectionManager.toXClass( idClass.value() );
boolean isComponent = true;
boolean propertyAnnotated = entityBinder.isPropertyAnnotated( compositeClass );
String propertyAccessor = entityBinder.getPropertyAccessor( compositeClass );
@@ -757,7 +758,7 @@
propertyAnnotated,
propertyAccessor, entityBinder,
true,
- false, mappings
+ false, mappings, inheritanceStatePerClass
);
inferredData = new PropertyPreloadedData(
propertyAccessor, "_identifierMapper", compositeClass
@@ -770,7 +771,7 @@
propertyAccessor, false,
entityBinder,
true, true,
- false, mappings
+ false, mappings, inheritanceStatePerClass
);
entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
persistentClass.setIdentifierMapper( mapper );
@@ -800,7 +801,7 @@
Nullability.NO_CONSTRAINT,
propertyAnnotatedElement.getProperty(),
propertyAnnotatedElement, classGenerators, entityBinder,
- false, false, false, mappings
+ false, false, false, mappings, inheritanceStatePerClass
);
}
else {
@@ -845,12 +846,13 @@
* Change EntityBinder by side effect
*/
private static List<PropertyData> getElementsToProcess(
- XClass clazzToProcess, Map<XClass, InheritanceState> inheritanceStatePerClass,
+ PersistentClass persistentClass, XClass clazzToProcess,
+ Map<XClass, InheritanceState> inheritanceStatePerClass,
PropertyHolder propertyHolder, EntityBinder entityBinder, ExtendedMappings mappings
) {
InheritanceState inheritanceState = inheritanceStatePerClass.get( clazzToProcess );
- List<XClass> classesToProcess = orderClassesToBeProcessed(
- clazzToProcess, inheritanceStatePerClass, inheritanceState, mappings
+ List<XClass> classesToProcess = getMappedSuperclassesTillNextEntityOrdered(
+ persistentClass, clazzToProcess, inheritanceStatePerClass, mappings
);
List<PropertyData> elements = new ArrayList<PropertyData>();
int deep = classesToProcess.size();
@@ -858,7 +860,7 @@
assert !inheritanceState.isEmbeddableSuperclass;
Boolean isExplicitPropertyAnnotated = null;
- String explicitAccessType = null;
+ String explicitAccessType;
if ( inheritanceState.hasParents ) {
InheritanceState superEntityState =
InheritanceState.getSuperEntityInheritanceState(
@@ -942,14 +944,17 @@
null;
}
- private static List<XClass> orderClassesToBeProcessed(
- XClass annotatedClass, Map<XClass, InheritanceState> inheritanceStatePerClass,
- InheritanceState inheritanceState, ExtendedMappings mappings
+ private static List<XClass> getMappedSuperclassesTillNextEntityOrdered(
+ PersistentClass persistentClass, XClass annotatedClass,
+ Map<XClass, InheritanceState> inheritanceStatePerClass,
+ ExtendedMappings mappings
) {
+
//ordered to allow proper messages on properties subclassing
List<XClass> classesToProcess = new ArrayList<XClass>();
XClass currentClassInHierarchy = annotatedClass;
InheritanceState superclassState;
+ final ReflectionManager reflectionManager = mappings.getReflectionManager();
do {
classesToProcess.add( 0, currentClassInHierarchy );
XClass superClass = currentClassInHierarchy;
@@ -957,13 +962,36 @@
superClass = superClass.getSuperclass();
superclassState = inheritanceStatePerClass.get( superClass );
}
- while ( superClass != null && !mappings.getReflectionManager()
+ while ( superClass != null && !reflectionManager
.equals( superClass, Object.class ) && superclassState == null );
currentClassInHierarchy = superClass;
}
while ( superclassState != null && superclassState.isEmbeddableSuperclass );
+ //add @MappedSuperclass in the metadata
+ // classes from 0 to n-1 are @MappedSuperclass and should be linked
+ org.hibernate.mapping.MappedSuperclass mappedSuperclass = null;
+ final InheritanceState superEntityState =
+ InheritanceState.getSuperEntityInheritanceState(annotatedClass,
inheritanceStatePerClass, reflectionManager);
+ PersistentClass superEntity =
+ superEntityState != null ?
+ mappings.getClass( superEntityState.clazz.getName() ) :
+ null;
+ final int lastMappedSuperclass = classesToProcess.size() - 1;
+ for ( int index = 0 ; index < lastMappedSuperclass ; index++ ) {
+ org.hibernate.mapping.MappedSuperclass parentSuperclass = mappedSuperclass;
+ final Class<?> type = mappings.getReflectionManager().toClass(
classesToProcess.get( index ) );
+ //add MAppedSuperclass if not already there
+ mappedSuperclass = mappings.getMappedSuperclass( type );
+ if (mappedSuperclass == null) {
+ mappedSuperclass = new org.hibernate.mapping.MappedSuperclass(parentSuperclass,
superEntity );
+ mappings.addMappedSuperclass( type, mappedSuperclass );
+ }
+ }
+ if (mappedSuperclass != null) {
+ persistentClass.setSuperMappedSuperclass(mappedSuperclass);
+ }
return classesToProcess;
}
@@ -1127,7 +1155,7 @@
" or set an explicit target attribute (eg @OneToMany(target=) or use an
explicit @Type"
);
}
- final boolean currentHasIdentifier = addProperty( p, elements, localPropertyAccessor,
mappings );
+ final boolean currentHasIdentifier = addProperty( annotatedClass, p, elements,
localPropertyAccessor, mappings );
hasIdentifier = hasIdentifier || currentHasIdentifier;
}
return hasIdentifier;
@@ -1173,17 +1201,17 @@
}
private static boolean addProperty(
- XProperty property, List<PropertyData> annElts,
+ XClass declaringClass, XProperty property, List<PropertyData> annElts,
String propertyAccessor, ExtendedMappings mappings
) {
boolean hasIdentifier = false;
PropertyData propertyAnnotatedElement = new PropertyInferredData(
- property, propertyAccessor,
+ declaringClass, property, propertyAccessor,
mappings.getReflectionManager() );
if ( !mustBeSkipped( propertyAnnotatedElement.getProperty(), mappings ) ) {
/*
* put element annotated by @Id in front
- * since it has to be parsed before any assoctation by Hibernate
+ * since it has to be parsed before any association by Hibernate
*/
final XAnnotatedElement element = propertyAnnotatedElement.getProperty();
if ( element.isAnnotationPresent( Id.class ) || element.isAnnotationPresent(
EmbeddedId.class ) ) {
@@ -1212,7 +1240,8 @@
PropertyHolder propertyHolder, Nullability nullability, XProperty property,
PropertyData inferredData, HashMap<String, IdGenerator> classGenerators,
EntityBinder entityBinder, boolean isIdentifierMapper,
- boolean isComponentEmbedded, boolean inSecondPass, ExtendedMappings mappings
+ boolean isComponentEmbedded, boolean inSecondPass, ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
)
throws MappingException {
/**
@@ -1389,7 +1418,9 @@
propertyAnnotated,
propertyAccessor, entityBinder,
false,
- isIdentifierMapper, mappings
+ isIdentifierMapper,
+ mappings,
+ inheritanceStatePerClass
);
log.debug(
@@ -1426,7 +1457,7 @@
propBinder.setProperty( property );
propBinder.setReturnedClass( inferredData.getPropertyClass() );
propBinder.setMappings( mappings );
-
+ propBinder.setDeclaringClass( inferredData.getDeclaringClass() );
Property prop = propBinder.bind();
propBinder.getSimpleValueBinder().setVersion(true);
rootClass.setVersion( prop );
@@ -1791,6 +1822,8 @@
collectionBinder.setLocalGenerators( localGenerators );
}
+ collectionBinder.setInheritanceStatePerClass( inheritanceStatePerClass );
+ collectionBinder.setDeclaringClass( inferredData.getDeclaringClass() );
collectionBinder.bind();
}
@@ -1810,7 +1843,7 @@
bindComponent(
inferredData, propertyHolder, propertyAnnotated, propertyAccessor, entityBinder,
isIdentifierMapper,
- mappings, isComponentEmbedded
+ mappings, isComponentEmbedded, inheritanceStatePerClass
);
}
else {
@@ -1844,6 +1877,7 @@
propBinder.setInsertable( false );
propBinder.setUpdatable( false );
}
+ propBinder.setDeclaringClass( inferredData.getDeclaringClass() );
propBinder.bind();
}
}
@@ -1955,12 +1989,13 @@
boolean propertyAnnotated,
String propertyAccessor, EntityBinder entityBinder,
boolean isIdentifierMapper,
- ExtendedMappings mappings, boolean isComponentEmbedded
+ ExtendedMappings mappings, boolean isComponentEmbedded,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
) {
Component comp = fillComponent(
propertyHolder, inferredData, propertyAnnotated, propertyAccessor, true,
entityBinder,
isComponentEmbedded, isIdentifierMapper,
- false, mappings
+ false, mappings, inheritanceStatePerClass
);
XProperty property = inferredData.getProperty();
setupComponentTuplizer( property, comp );
@@ -1971,24 +2006,28 @@
binder.setProperty( inferredData.getProperty() );
binder.setPropertyAccessorName( inferredData.getDefaultAccess() );
Property prop = binder.make();
- propertyHolder.addProperty( prop );
+ propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
}
public static Component fillComponent(
PropertyHolder propertyHolder, PropertyData inferredData,
boolean propertyAnnotated, String propertyAccessor, boolean isNullable,
EntityBinder entityBinder,
- boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass,
ExtendedMappings mappings
+ boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass,
+ ExtendedMappings mappings, Map<XClass, InheritanceState>
inheritanceStatePerClass
) {
- return fillComponent(propertyHolder, inferredData, null, propertyAnnotated,
propertyAccessor, isNullable, entityBinder, isComponentEmbedded, isIdentifierMapper,
inSecondPass, mappings);
+ return fillComponent(propertyHolder, inferredData, null, propertyAnnotated,
propertyAccessor,
+ isNullable, entityBinder, isComponentEmbedded, isIdentifierMapper, inSecondPass,
mappings,
+ inheritanceStatePerClass);
}
public static Component fillComponent(
PropertyHolder propertyHolder, PropertyData inferredData, PropertyData
baseInferredData,
boolean propertyAnnotated, String propertyAccessor, boolean isNullable,
EntityBinder entityBinder,
- boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass,
ExtendedMappings mappings
+ boolean isComponentEmbedded, boolean isIdentifierMapper, boolean inSecondPass,
ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
) {
/**
@@ -2057,15 +2096,12 @@
);
superClass = superClass.getSuperclass();
}
- if(baseClassElements != null)
- {
- if(!hasIdClassAnnotations(inferredData.getPropertyClass()))
- {
- for(int i=0; i < classElements.size(); i++)
- {
- classElements.set(i, baseClassElements.get(i)); //this works since they are
in the same order
- }
- }
+ if ( baseClassElements != null ) {
+ if ( !hasIdClassAnnotations( inferredData.getPropertyClass() ) ) {
+ for ( int i = 0; i < classElements.size(); i++ ) {
+ classElements.set( i, baseClassElements.get( i ) ); //this works since they are in
the same order
+ }
+ }
}
for (PropertyData propertyAnnotatedElement : classElements) {
processElementAnnotations(
@@ -2074,7 +2110,7 @@
Nullability.FORCED_NOT_NULL,
propertyAnnotatedElement.getProperty(), propertyAnnotatedElement,
new HashMap<String, IdGenerator>(), entityBinder, isIdentifierMapper,
isComponentEmbedded,
- inSecondPass, mappings
+ inSecondPass, mappings, inheritanceStatePerClass
);
}
return comp;
@@ -2087,10 +2123,13 @@
boolean isComposite,
boolean isPropertyAnnotated,
String propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
- boolean isIdentifierMapper, ExtendedMappings mappings
+ boolean isIdentifierMapper, ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
) {
- bindId(generatorType, generatorName, inferredData, null, columns, propertyHolder,
localGenerators, isComposite, isPropertyAnnotated, propertyAccessor, entityBinder,
isEmbedded, isIdentifierMapper, mappings);
+ bindId(generatorType, generatorName, inferredData, null, columns, propertyHolder,
+ localGenerators, isComposite, isPropertyAnnotated, propertyAccessor, entityBinder,
+ isEmbedded, isIdentifierMapper, mappings, inheritanceStatePerClass);
}
private static void bindId(
@@ -2100,7 +2139,8 @@
boolean isComposite,
boolean isPropertyAnnotated,
String propertyAccessor, EntityBinder entityBinder, boolean isEmbedded,
- boolean isIdentifierMapper, ExtendedMappings mappings
+ boolean isIdentifierMapper, ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
) {
/*
@@ -2121,7 +2161,7 @@
if ( isComposite ) {
id = fillComponent(
propertyHolder, inferredData, baseInferredData, isPropertyAnnotated,
propertyAccessor,
- false, entityBinder, isEmbedded, isIdentifierMapper, false, mappings
+ false, entityBinder, isEmbedded, isIdentifierMapper, false, mappings,
inheritanceStatePerClass
);
Component componentId = (Component) id;
componentId.setKey( true );
@@ -2247,7 +2287,7 @@
binder.setProperty(inferredData.getProperty());
Property prop = binder.make();
//composite FK columns are in the same table so its OK
- propertyHolder.addProperty( prop, columns );
+ propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() );
}
protected static void defineFetchingStrategy(ToOne toOne, XProperty property) {
@@ -2397,7 +2437,7 @@
binder.setCascade( cascadeStrategy );
Property prop = binder.make();
//composite FK columns are in the same table so its OK
- propertyHolder.addProperty( prop, columns );
+ propertyHolder.addProperty( prop, columns, inferredData.getDeclaringClass() );
}
private static String generatorType(GenerationType generatorEnum) {
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -135,6 +135,7 @@
private transient ReflectionManager reflectionManager;
private boolean isDefaultProcessed = false;
private boolean isValidatorNotPresentLogged;
+ private Map<Class<?>, org.hibernate.mapping.MappedSuperclass>
mappedSuperclasses;
public AnnotationConfiguration() {
super();
@@ -260,6 +261,7 @@
namingStrategy = EJB3NamingStrategy.INSTANCE;
setEntityResolver( new EJB3DTDEntityResolver() );
anyMetaDefs = new HashMap<String, AnyMetaDef>();
+ mappedSuperclasses = new HashMap<Class<?>,
org.hibernate.mapping.MappedSuperclass>();
reflectionManager = new JavaReflectionManager();
( ( MetadataProviderInjector ) reflectionManager ).setMetadataProvider( new
JPAMetadataProvider() );
@@ -1178,7 +1180,14 @@
return inSecondPass;
}
+ public void addMappedSuperclass(Class<?> type,
org.hibernate.mapping.MappedSuperclass mappedSuperclass) {
+ mappedSuperclasses.put( type, mappedSuperclass );
+ }
+ public org.hibernate.mapping.MappedSuperclass getMappedSuperclass(Class<?> type)
{
+ return mappedSuperclasses.get( type );
+ }
+
public IdGenerator getGenerator(String name) {
return getGenerator( name, null );
}
@@ -1240,6 +1249,7 @@
}
}
+ //FIXME should be private but is part of the ExtendedMapping contract
public AnnotatedClassType addClassType(XClass clazz) {
AnnotatedClassType type;
if ( clazz.isAnnotationPresent( Entity.class ) ) {
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -28,6 +28,7 @@
import javax.persistence.JoinTable;
import org.hibernate.annotations.common.reflection.XClass;
+import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.cfg.annotations.EntityBinder;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.Join;
@@ -35,6 +36,7 @@
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table;
+import org.hibernate.mapping.MappedSuperclass;
/**
* @author Emmanuel Bernard
@@ -44,20 +46,23 @@
private Map<String, Join> joins;
private transient Map<String, Join> joinsPerRealTableName;
private EntityBinder entityBinder;
+ private final Map<XClass, InheritanceState> inheritanceStatePerClass;
public ClassPropertyHolder(
- PersistentClass persistentClass, XClass clazzToProcess, Map<String, Join> joins,
ExtendedMappings mappings
+ PersistentClass persistentClass, XClass clazzToProcess,
+ Map<String, Join> joins, ExtendedMappings mappings, Map<XClass,
InheritanceState> inheritanceStatePerClass
) {
super( persistentClass.getEntityName(), null, clazzToProcess, mappings );
this.persistentClass = persistentClass;
this.joins = joins;
+ this.inheritanceStatePerClass = inheritanceStatePerClass;
}
public ClassPropertyHolder(
PersistentClass persistentClass, XClass clazzToProcess, EntityBinder entityBinder,
- ExtendedMappings mappings
+ ExtendedMappings mappings, Map<XClass, InheritanceState>
inheritanceStatePerClass
) {
- this( persistentClass, clazzToProcess, entityBinder.getSecondaryTables(), mappings );
+ this( persistentClass, clazzToProcess, entityBinder.getSecondaryTables(), mappings,
inheritanceStatePerClass );
this.entityBinder = entityBinder;
}
@@ -65,30 +70,53 @@
return persistentClass.getEntityName();
}
- public void addProperty(Property prop, Ejb3Column[] columns) {
+ public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
//Ejb3Column.checkPropertyConsistency( ); //already called earlier
if ( columns[0].isSecondary() ) {
//TODO move the getJoin() code here?
- columns[0].getJoin().addProperty( prop );
+ final Join join = columns[0].getJoin();
+ addPropertyToJoin( prop, declaringClass, join );
}
else {
- addProperty( prop );
+ addProperty( prop, declaringClass );
}
}
+ public void addProperty(Property prop, XClass declaringClass) {
+ if ( prop.getValue() instanceof Component ) {
+ //TODO handle quote and non quote table comparison
+ String tableName = prop.getValue().getTable().getName();
+ if ( getJoinsPerRealTableName().containsKey( tableName ) ) {
+ final Join join = getJoinsPerRealTableName().get( tableName );
+ addPropertyToJoin( prop, declaringClass, join );
+ }
+ else {
+ addPropertyToPersistentClass( prop, declaringClass );
+ }
+ }
+ else {
+ addPropertyToPersistentClass( prop, declaringClass );
+ }
+ }
+
public Join addJoin(JoinTable joinTableAnn, boolean noDelayInPkColumnCreation) {
Join join = entityBinder.addJoin( joinTableAnn, this, noDelayInPkColumnCreation );
this.joins = entityBinder.getSecondaryTables();
return join;
}
- public void addProperty(Property prop) {
- if ( prop.getValue() instanceof Component ) {
- //TODO handle quote and non quote table comparison
- String tableName = prop.getValue().getTable().getName();
- if ( getJoinsPerRealTableName().containsKey( tableName ) ) {
- getJoinsPerRealTableName().get( tableName ).addProperty( prop );
+ private void addPropertyToPersistentClass(Property prop, XClass declaringClass) {
+ if ( declaringClass != null ) {
+ final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass
);
+ if ( inheritanceState == null ) {
+ throw new AssertionFailure(
+ "Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
+ );
}
+ if ( inheritanceState.isEmbeddableSuperclass ) {
+ persistentClass.addMappedsuperclassProperty(prop);
+ addPropertyToMappedSuperclass( prop, declaringClass );
+ }
else {
persistentClass.addProperty( prop );
}
@@ -98,6 +126,34 @@
}
}
+ private void addPropertyToMappedSuperclass(Property prop, XClass declaringClass) {
+ final ExtendedMappings mappings = getMappings();
+ final Class type = mappings.getReflectionManager().toClass( declaringClass );
+ MappedSuperclass superclass = mappings.getMappedSuperclass( type );
+ superclass.addProperty( prop );
+ }
+
+ private void addPropertyToJoin(Property prop, XClass declaringClass, Join join) {
+ if ( declaringClass != null ) {
+ final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass
);
+ if ( inheritanceState == null ) {
+ throw new AssertionFailure(
+ "Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
+ );
+ }
+ if ( inheritanceState.isEmbeddableSuperclass ) {
+ join.addMappedsuperclassProperty(prop);
+ addPropertyToMappedSuperclass( prop, declaringClass );
+ }
+ else {
+ join.addProperty( prop );
+ }
+ }
+ else {
+ join.addProperty( prop );
+ }
+ }
+
/**
* Needed for proper compliance with naming strategy, the property table
* can be overriden if the properties are part of secondary tables
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/CollectionPropertyHolder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -62,7 +62,7 @@
return collection.getCollectionTable();
}
- public void addProperty(Property prop) {
+ public void addProperty(Property prop, XClass declaringClass) {
throw new AssertionFailure( "Cannot add property to a collection" );
}
@@ -86,7 +86,7 @@
return collection.getOwner().getEntityName();
}
- public void addProperty(Property prop, Ejb3Column[] columns) {
+ public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
//Ejb3Column.checkPropertyConsistency( ); //already called earlier
throw new AssertionFailure( "addProperty to a join table of a collection: does it
make sense?" );
}
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/ComponentPropertyHolder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -28,6 +28,7 @@
import javax.persistence.JoinTable;
import org.hibernate.AnnotationException;
+import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.mapping.Component;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.KeyValue;
@@ -49,7 +50,7 @@
return component.getComponentClassName();
}
- public void addProperty(Property prop, Ejb3Column[] columns) {
+ public void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass) {
//Ejb3Column.checkPropertyConsistency( ); //already called earlier
/*
* Check table matches between the component and the columns
@@ -68,7 +69,7 @@
);
}
}
- addProperty( prop );
+ addProperty( prop, declaringClass );
}
public Join addJoin(JoinTable joinTableAnn, boolean noDelayInPkColumnCreation) {
@@ -97,7 +98,7 @@
return component.getTable();
}
- public void addProperty(Property prop) {
+ public void addProperty(Property prop, XClass declaringClass) {
component.addProperty( prop );
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java 2009-10-28
18:03:10 UTC (rev 17870)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/Ejb3JoinColumn.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -36,6 +36,7 @@
import org.hibernate.annotations.JoinColumnOrFormula;
import org.hibernate.annotations.JoinColumnsOrFormulas;
import org.hibernate.annotations.JoinFormula;
+import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.Join;
import org.hibernate.mapping.PersistentClass;
@@ -355,9 +356,11 @@
* Override persistent class on oneToMany Cases for late settings
* Must only be used on second level pass binding
*/
- public void setPersistentClass(PersistentClass persistentClass, Map<String, Join>
joins) {
+ public void setPersistentClass(PersistentClass persistentClass,
+ Map<String, Join> joins,
+ Map<XClass, InheritanceState> inheritanceStatePerClass) {
//FIXME shouldn't we deduce the classname from the persistentclasS?
- this.propertyHolder = PropertyHolderBuilder.buildPropertyHolder( persistentClass,
joins, getMappings() );
+ this.propertyHolder = PropertyHolderBuilder.buildPropertyHolder( persistentClass,
joins, getMappings(), inheritanceStatePerClass );
}
public static void checkIfJoinColumn(Object columns, PropertyHolder holder, PropertyData
property) {
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/ExtendedMappings.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -27,6 +27,8 @@
import java.util.Map;
import java.util.Properties;
+import javax.persistence.MappedSuperclass;
+
import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
import org.hibernate.annotations.AnyMetaDef;
@@ -124,6 +126,7 @@
public AnnotatedClassType getClassType(XClass clazz);
/**
+ * FIXME should be private but will this break things?
* Add a class type.
*
* @param clazz The XClass mapping.
@@ -157,6 +160,15 @@
public AnyMetaDef getAnyMetaDef(String name);
- public boolean isInSecondPass();
-
+ public boolean isInSecondPass();
+
+ /**
+ * add a new MappedSuperclass
+ */
+ public void addMappedSuperclass(Class<?> type,
org.hibernate.mapping.MappedSuperclass mappedSuperclass);
+
+ /**
+ * Get a MappedSuperclass or null if not mapped
+ */
+ org.hibernate.mapping.MappedSuperclass getMappedSuperclass(Class<?> type);
}
\ No newline at end of file
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/OneToOneSecondPass.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -131,7 +131,7 @@
path, mappings
) ).doSecondPass( persistentClasses );
//no column associated since its a one to one
- propertyHolder.addProperty( prop );
+ propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
}
else {
//this is a many to one with Formula
@@ -162,7 +162,7 @@
);
}
if ( otherSideProperty.getValue() instanceof OneToOne ) {
- propertyHolder.addProperty( prop );
+ propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
}
else if ( otherSideProperty.getValue() instanceof ManyToOne ) {
Iterator it = otherSide.getJoinIterator();
@@ -208,7 +208,7 @@
mappedByJoin.addProperty( prop );
}
else {
- propertyHolder.addProperty( prop );
+ propertyHolder.addProperty( prop, inferredData.getDeclaringClass() );
}
value.setReferencedPropertyName( mappedBy );
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyData.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyData.java 2009-10-28
18:03:10 UTC (rev 17870)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyData.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -33,33 +33,43 @@
* @return default member access (whether field or property)
* @throws MappingException No getter or field found or wrong JavaBean spec usage
*/
- public String getDefaultAccess();
+ String getDefaultAccess();
/**
* @return property name
* @throws MappingException No getter or field found or wrong JavaBean spec usage
*/
- public String getPropertyName() throws MappingException;
+ String getPropertyName() throws MappingException;
/**
* Returns the returned class itself or the element type if an array
*/
- public XClass getClassOrElement() throws MappingException;
+ XClass getClassOrElement() throws MappingException;
/**
* Return the class itself
*/
- public XClass getPropertyClass() throws MappingException;
+ XClass getPropertyClass() throws MappingException;
/**
* Returns the returned class name itself or the element type if an array
*/
- public String getClassOrElementName() throws MappingException;
+ String getClassOrElementName() throws MappingException;
/**
* Returns the returned class name itself
*/
- public String getTypeName() throws MappingException;
+ String getTypeName() throws MappingException;
- public XProperty getProperty();
+ /**
+ * Return the Hibernate mapping property
+ */
+ XProperty getProperty();
+
+ /**
+ * Return the Class the property is declared on
+ * If the property is declared on a @MappedSuperclass,
+ * this class will be different than the PersistentClass's class
+ */
+ XClass getDeclaringClass();
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolder.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -32,6 +32,7 @@
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.mapping.Table;
+import org.hibernate.annotations.common.reflection.XClass;
/**
* Property holder abstract property containers from their direct implementation
@@ -45,8 +46,10 @@
Table getTable();
- void addProperty(Property prop);
+ void addProperty(Property prop, XClass declaringClass);
+ void addProperty(Property prop, Ejb3Column[] columns, XClass declaringClass);
+
KeyValue getIdentifier();
PersistentClass getPersistentClass();
@@ -71,7 +74,5 @@
String getEntityName();
- void addProperty(Property prop, Ejb3Column[] columns);
-
Join addJoin(JoinTable joinTableAnn, boolean noDelayInPkColumnCreation);
}
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyHolderBuilder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -47,9 +47,10 @@
PersistentClass persistentClass,
EntityBinder entityBinder,
//Map<String, Join> joins,
- ExtendedMappings mappings
+ ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
) {
- return new ClassPropertyHolder( persistentClass, clazzToProcess, entityBinder, mappings
);
+ return new ClassPropertyHolder( persistentClass, clazzToProcess, entityBinder,
mappings, inheritanceStatePerClass );
}
/**
@@ -82,8 +83,9 @@
*/
public static PropertyHolder buildPropertyHolder(
PersistentClass persistentClass, Map<String, Join> joins,
- ExtendedMappings mappings
+ ExtendedMappings mappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
) {
- return new ClassPropertyHolder( persistentClass, null, joins, mappings );
+ return new ClassPropertyHolder( persistentClass, null, joins, mappings,
inheritanceStatePerClass );
}
}
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyInferredData.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -41,11 +41,14 @@
private final XProperty property;
private final ReflectionManager reflectionManager;
+ private final XClass declaringClass;
+
/**
* Take the annoted element for lazy process
*/
- public PropertyInferredData(XProperty property, String propertyAccessor,
ReflectionManager reflectionManager) {
+ public PropertyInferredData(XClass declaringClass, XProperty property, String
propertyAccessor, ReflectionManager reflectionManager) {
+ this.declaringClass = declaringClass;
this.property = property;
this.defaultAccess = propertyAccessor;
this.reflectionManager = reflectionManager;
@@ -91,4 +94,8 @@
public XProperty getProperty() {
return property;
}
+
+ public XClass getDeclaringClass() {
+ return declaringClass;
+ }
}
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/PropertyPreloadedData.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -67,4 +67,10 @@
public XProperty getProperty() {
return null; //instead of UnsupportedOperationException
}
+
+ public XClass getDeclaringClass() {
+ //Preloaded properties are artificial wrapper for colleciton element accesses
+ //and idClass creation, ignore.
+ return null;
+ }
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/WrappedInferredData.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -51,6 +51,10 @@
return wrappedInferredData.getProperty();
}
+ public XClass getDeclaringClass() {
+ return wrappedInferredData.getDeclaringClass();
+ }
+
public XClass getPropertyClass() throws MappingException {
return wrappedInferredData.getPropertyClass();
}
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -32,17 +32,19 @@
import java.util.StringTokenizer;
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
+import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.FetchType;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.MapKey;
+import javax.persistence.MapKeyColumn;
import javax.persistence.OneToMany;
-import javax.persistence.ElementCollection;
-import javax.persistence.MapKeyColumn;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.hibernate.AnnotationException;
-import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
import org.hibernate.annotations.BatchSize;
@@ -71,6 +73,7 @@
import org.hibernate.annotations.SortType;
import org.hibernate.annotations.Where;
import org.hibernate.annotations.WhereJoinTable;
+import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.cfg.AnnotatedClassType;
@@ -81,6 +84,7 @@
import org.hibernate.cfg.Ejb3JoinColumn;
import org.hibernate.cfg.ExtendedMappings;
import org.hibernate.cfg.IndexColumn;
+import org.hibernate.cfg.InheritanceState;
import org.hibernate.cfg.PropertyData;
import org.hibernate.cfg.PropertyHolder;
import org.hibernate.cfg.PropertyHolderBuilder;
@@ -105,8 +109,6 @@
import org.hibernate.mapping.SingleTableSubclass;
import org.hibernate.mapping.Table;
import org.hibernate.util.StringHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* Base class for binding different types of collections to Hibernate configuration
objects.
@@ -152,11 +154,18 @@
private Ejb3Column[] mapKeyColumns;
private Ejb3JoinColumn[] mapKeyManyToManyColumns;
protected HashMap<String, IdGenerator> localGenerators;
+ protected Map<XClass, InheritanceState> inheritanceStatePerClass;
+ private XClass declaringClass;
+ private boolean declaringClassSet;
public void setUpdatable(boolean updatable) {
this.updatable = updatable;
}
+ public void setInheritanceStatePerClass(Map<XClass, InheritanceState>
inheritanceStatePerClass) {
+ this.inheritanceStatePerClass = inheritanceStatePerClass;
+ }
+
public void setInsertable(boolean insertable) {
this.insertable = insertable;
}
@@ -333,6 +342,11 @@
this.propertyName = propertyName;
}
+ public void setDeclaringClass(XClass declaringClass) {
+ this.declaringClass = declaringClass;
+ this.declaringClassSet = true;
+ }
+
public void bind() {
this.collection = createCollection( propertyHolder.getPersistentClass() );
log.debug( "Collection role: {}", StringHelper.qualify(
propertyHolder.getPath(), propertyName ) );
@@ -443,6 +457,7 @@
}
//TODO reducce tableBinder != null and oneToMany
XClass collectionType = getCollectionType();
+ if ( inheritanceStatePerClass == null) throw new AssertionFailure(
"inheritanceStatePerClass not set" );
SecondPass sp = getSecondPass(
fkJoinColumns,
joinColumns,
@@ -482,7 +497,8 @@
binder.setUpdatable( updatable );
Property prop = binder.make();
//we don't care about the join stuffs because the column is on the association
table.
- propertyHolder.addProperty( prop );
+ if (! declaringClassSet) throw new AssertionFailure( "DeclaringClass is not set in
CollectionBinder while binding" );
+ propertyHolder.addProperty( prop, declaringClass );
}
private void defineFetchingStrategy() {
@@ -569,7 +585,6 @@
final boolean ignoreNotFound, final boolean unique,
final TableBinder assocTableBinder, final ExtendedMappings mappings
) {
-
return new CollectionSecondPass( mappings, collection ) {
public void secondPass(java.util.Map persistentClasses, java.util.Map inheritedMetas)
@@ -591,7 +606,8 @@
Ejb3JoinColumn[] keyColumns, Ejb3JoinColumn[] inverseColumns, Ejb3Column[]
elementColumns,
boolean isEmbedded,
XProperty property, boolean unique,
- TableBinder associationTableBinder, boolean ignoreNotFound, ExtendedMappings mappings
+ TableBinder associationTableBinder,
+ boolean ignoreNotFound, ExtendedMappings mappings
) {
PersistentClass persistentClass = (PersistentClass) persistentClasses.get(
collType.getName() );
boolean reversePropertyInJoin = false;
@@ -627,7 +643,8 @@
collType,
cascadeDeleteEnabled,
ignoreNotFound, hqlOrderBy,
- mappings
+ mappings,
+ inheritanceStatePerClass
);
return true;
}
@@ -651,7 +668,8 @@
protected void bindOneToManySecondPass(
Collection collection, Map persistentClasses, Ejb3JoinColumn[] fkJoinColumns,
XClass collectionType,
- boolean cascadeDeleteEnabled, boolean ignoreNotFound, String hqlOrderBy,
ExtendedMappings extendedMappings
+ boolean cascadeDeleteEnabled, boolean ignoreNotFound, String hqlOrderBy,
ExtendedMappings extendedMappings,
+ Map<XClass, InheritanceState> inheritanceStatePerClass
) {
log.debug("Binding a OneToMany: {}.{} through a foreign key",
propertyHolder.getEntityName(), propertyName);
@@ -677,7 +695,7 @@
}
oneToMany.setAssociatedClass( associatedClass );
for (Ejb3JoinColumn column : fkJoinColumns) {
- column.setPersistentClass( associatedClass, joins );
+ column.setPersistentClass( associatedClass, joins, inheritanceStatePerClass );
column.setJoins( joins );
collection.setCollectionTable( column.getTable() );
}
@@ -1221,7 +1239,7 @@
else if ( anyAnn != null ) {
//@ManyToAny
//Make sure that collTyp is never used during the @ManyToAny branch: it will be set to
void.class
- PropertyData inferredData = new PropertyInferredData( property,
"unsupported", mappings.getReflectionManager() );
+ PropertyData inferredData = new PropertyInferredData(null, property,
"unsupported", mappings.getReflectionManager() );
//override the table
for (Ejb3Column column : inverseJoinColumns) {
column.setTable( collValue.getCollectionTable() );
@@ -1284,7 +1302,7 @@
Component component = AnnotationBinder.fillComponent(
holder, inferredData, isPropertyAnnotated, isPropertyAnnotated ?
"property" : "field", true,
entityBinder, false, false,
- true, mappings
+ true, mappings, inheritanceStatePerClass
);
collValue.setElement( component );
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/IdBagBinder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -68,7 +68,7 @@
SimpleValueBinder simpleValue = new SimpleValueBinder();
PropertyData propertyData = new WrappedInferredData(
- new PropertyInferredData( property, null, //default access should not be useful
+ new PropertyInferredData( null, property, null, //default access should not be
useful
mappings.getReflectionManager() ),
"id" );
Ejb3Column[] idColumns = Ejb3Column.buildColumnFromAnnotation(
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ListBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ListBinder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/ListBinder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -25,13 +25,15 @@
import java.util.Map;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
import org.hibernate.annotations.OrderBy;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
-import org.hibernate.util.StringHelper;
import org.hibernate.cfg.CollectionSecondPass;
import org.hibernate.cfg.Ejb3Column;
import org.hibernate.cfg.Ejb3JoinColumn;
@@ -45,8 +47,7 @@
import org.hibernate.mapping.OneToMany;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.SimpleValue;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import org.hibernate.util.StringHelper;
/**
* Bind a list to the underlying Hibernate configuration
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/MapBinder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -35,8 +35,8 @@
import org.hibernate.AssertionFailure;
import org.hibernate.FetchMode;
import org.hibernate.MappingException;
+import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.MapKeyManyToMany;
-import org.hibernate.annotations.MapKey;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
import org.hibernate.cfg.AnnotatedClassType;
@@ -232,7 +232,7 @@
Component component = AnnotationBinder.fillComponent(
holder, inferredData, isPropertyAnnotated, isPropertyAnnotated ?
"property" : "field", true,
entityBinder, false, false,
- true, mappings
+ true, mappings, inheritanceStatePerClass
);
mapValue.setIndex( component );
}
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java 2009-10-28
18:03:10 UTC (rev 17870)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -34,6 +34,7 @@
import org.hibernate.annotations.OptimisticLock;
import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.annotations.common.reflection.XProperty;
+import org.hibernate.annotations.common.AssertionFailure;
import org.hibernate.cfg.Ejb3Column;
import org.hibernate.cfg.ExtendedMappings;
import org.hibernate.cfg.PropertyHolder;
@@ -62,6 +63,8 @@
private boolean updatable = true;
private String cascade;
private SimpleValueBinder simpleValueBinder;
+ private XClass declaringClass;
+ private boolean declaringClassSet;
/*
* property can be null
@@ -118,11 +121,19 @@
this.mappings = mappings;
}
+ public void setDeclaringClass(XClass declaringClass) {
+ this.declaringClass = declaringClass;
+ this.declaringClassSet = true;
+ }
+
private void validateBind() {
if (property.isAnnotationPresent(Immutable.class)) {
throw new AnnotationException("@Immutable on property not allowed. " +
"Only allowed on entity level or on a collection.");
- }
+ }
+ if ( !declaringClassSet ) {
+ throw new AssertionFailure( "declaringClass has not been set before a
bind");
+ }
}
private void validateMake() {
@@ -146,7 +157,7 @@
SimpleValue propertyValue = simpleValueBinder.make();
setValue( propertyValue );
Property prop = make();
- holder.addProperty( prop, columns );
+ holder.addProperty( prop, columns, declaringClass );
return prop;
}
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/Join.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Join.java 2009-10-28 18:03:10 UTC
(rev 17870)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/Join.java 2009-10-28 18:14:25 UTC
(rev 17871)
@@ -39,6 +39,7 @@
private static final Alias PK_ALIAS = new Alias(15, "PK");
private ArrayList properties = new ArrayList();
+ private ArrayList declaredProperties = new ArrayList();
private Table table;
private KeyValue key;
private PersistentClass persistentClass;
@@ -59,8 +60,18 @@
public void addProperty(Property prop) {
properties.add(prop);
+ declaredProperties.add(prop);
prop.setPersistentClass( getPersistentClass() );
}
+ public void addMappedsuperclassProperty(Property prop) {
+ properties.add(prop);
+ prop.setPersistentClass( getPersistentClass() );
+ }
+
+ public Iterator getDeclaredPropertyIterator() {
+ return declaredProperties.iterator();
+ }
+
public boolean containsProperty(Property prop) {
return properties.contains(prop);
}
Added: core/trunk/core/src/main/java/org/hibernate/mapping/MappedSuperclass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/MappedSuperclass.java
(rev 0)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/MappedSuperclass.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -0,0 +1,67 @@
+package org.hibernate.mapping;
+
+import java.util.*;
+import java.util.List;
+
+/**
+ * Represents a @MappedSuperclass.
+ * A @MappedSuperclass can be a superclass of an @Entity (root or not)
+ *
+ * This class primary goal is to give a representation to @MappedSuperclass
+ * in the metamodel in order to reflect them in the JPA 2 metamodel.
+ *
+ * Do not use outside this use case.
+ *
+ * A proper redesign will be evluated in Hibernate 4
+ *
+ * @author Emmanuel Bernard
+ */
+public class MappedSuperclass {
+ private final MappedSuperclass superMappedSuperclass;
+ private final PersistentClass superPersistentClass;
+ private final List properties;
+
+ public MappedSuperclass(MappedSuperclass superMappedSuperclass, PersistentClass
superPersistentClass) {
+ this.superMappedSuperclass = superMappedSuperclass;
+ this.superPersistentClass = superPersistentClass;
+ this.properties = new ArrayList();
+ }
+
+ /**
+ * Returns the first superclass marked as @MappedSuperclass or null if:
+ * - none exists
+ * - or the first persistent superclass found is an @Entity
+ *
+ * @return the super MappedSuperclass
+ */
+ public MappedSuperclass getSuperMappedSuperclass() {
+ return superMappedSuperclass;
+ }
+
+ /**
+ * Returns the PersistentClass of the first superclass marked as @Entity
+ * or null if none exists
+ *
+ * @return the PersistentClass of the superclass
+ */
+ public PersistentClass getSuperPersistentClass() {
+ return superPersistentClass;
+ }
+
+ public Iterator getPropertyIterator() {
+ return properties.iterator();
+ }
+
+ public void addProperty(Property p) {
+ //Do not add duplicate properties
+ //TODO is it efficient enough?
+ String name = p.getName();
+ Iterator it = properties.iterator();
+ while (it.hasNext()) {
+ if ( name.equals( ((Property)it.next()).getName() ) ) {
+ return;
+ }
+ }
+ properties.add(p);
+ }
+}
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java 2009-10-28
18:03:10 UTC (rev 17870)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/PersistentClass.java 2009-10-28
18:14:25 UTC (rev 17871)
@@ -62,6 +62,7 @@
private String discriminatorValue;
private boolean lazy;
private ArrayList properties = new ArrayList();
+ private ArrayList declaredProperties = new ArrayList();
private final ArrayList subclasses = new ArrayList();
private final ArrayList subclassProperties = new ArrayList();
private final ArrayList subclassTables = new ArrayList();
@@ -96,6 +97,7 @@
private java.util.Map tuplizerImpls;
protected int optimisticLockMode;
+ private MappedSuperclass superMappedSuperclass;
public String getClassName() {
return className;
@@ -221,6 +223,7 @@
public void addProperty(Property p) {
properties.add(p);
+ declaredProperties.add(p);
p.setPersistentClass(this);
}
@@ -811,4 +814,31 @@
}
public abstract boolean isLazyPropertiesCacheable();
+
+ // The following methods are added to support @MappedSuperclass in the metamodel
+ public Iterator getDeclaredPropertyIterator() {
+ ArrayList iterators = new ArrayList();
+ iterators.add( declaredProperties.iterator() );
+ for ( int i = 0; i < joins.size(); i++ ) {
+ Join join = ( Join ) joins.get( i );
+ iterators.add( join.getDeclaredPropertyIterator() );
+ }
+ return new JoinedIterator( iterators );
+ }
+
+ public void addMappedsuperclassProperty(Property p) {
+ properties.add(p);
+ p.setPersistentClass(this);
+ }
+
+ public MappedSuperclass getSuperMappedSuperclass() {
+ return superMappedSuperclass;
+ }
+
+ public void setSuperMappedSuperclass(MappedSuperclass superMappedSuperclass) {
+ this.superMappedSuperclass = superMappedSuperclass;
+ }
+
+ // End of @Mappedsuperclass support
+
}
\ No newline at end of file
Modified: core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java
===================================================================
--- core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java 2009-10-28 18:03:10
UTC (rev 17870)
+++ core/trunk/core/src/main/java/org/hibernate/mapping/Subclass.java 2009-10-28 18:14:25
UTC (rev 17871)
@@ -93,6 +93,12 @@
super.addProperty(p);
getSuperclass().addSubclassProperty(p);
}
+
+ public void addMappedsuperClassProperty(Property p) {
+ super.addMappedsuperclassProperty( p );
+ getSuperclass().addSubclassProperty(p);
+ }
+
public void addJoin(Join j) {
super.addJoin(j);
getSuperclass().addSubclassJoin(j);