Author: hardy.ferentschik
Date: 2009-12-11 14:14:01 -0500 (Fri, 11 Dec 2009)
New Revision: 18211
Modified:
core/trunk/annotations/src/main/java/org/hibernate/annotations/AccessType.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/BinderHelper.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/access/AccessTest.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/access/Furniture.java
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/embedded/Country.java
Log:
HHH-4527
No functional changes yet. Just some cleanup and refactoring (extract method, encapsulate
field)
Modified: core/trunk/annotations/src/main/java/org/hibernate/annotations/AccessType.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/annotations/AccessType.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/main/java/org/hibernate/annotations/AccessType.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -23,17 +23,20 @@
*/
package org.hibernate.annotations;
-import static java.lang.annotation.ElementType.*;
import java.lang.annotation.Retention;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Target;
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
/**
* Property Access type
*
* @author Emmanuel Bernard
*/
-@Target({TYPE, METHOD, FIELD})
+@Target({ TYPE, METHOD, FIELD })
@Retention(RUNTIME)
public @interface AccessType {
String value();
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationBinder.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -176,6 +176,7 @@
* package)
*
* @author Emmanuel Bernard
+ * @author Hardy Ferentschik
*/
@SuppressWarnings("unchecked")
public final class AnnotationBinder {
@@ -247,7 +248,7 @@
}
public static void bindPackage(String packageName, ExtendedMappings mappings) {
- XPackage pckg = null;
+ XPackage pckg;
try {
pckg = mappings.getReflectionManager().packageForName( packageName );
}
@@ -438,153 +439,72 @@
bindFilterDefs(clazzToProcess, mappings);
}
- if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) //will be processed
by their subentities
- || AnnotatedClassType.NONE.equals( classType ) //to be ignored
- || AnnotatedClassType.EMBEDDABLE.equals( classType ) //allow embeddable element
declaration
- ) {
- if ( AnnotatedClassType.NONE.equals( classType )
- && clazzToProcess.isAnnotationPresent(
org.hibernate.annotations.Entity.class ) ) {
- log.warn( "Class annotated @org.hibernate.annotations.Entity but not
javax.persistence.Entity "
- + "(most likely a user error): {}", clazzToProcess.getName() );
- }
+ if( !isEntityClassType( clazzToProcess, classType ) ) {
return;
}
- if ( !classType.equals( AnnotatedClassType.ENTITY ) ) {
- //TODO make this test accurate by removing the none elements artifically added
- throw new AnnotationException(
- "Annotated class should have a @javax.persistence.Entity,
@javax.persistence.Embeddable or @javax.persistence.EmbeddedSuperclass annotation: "
+ clazzToProcess
- .getName()
- );
- }
- XAnnotatedElement annotatedClass = clazzToProcess;
+
log.info( "Binding entity from annotated class: {}", clazzToProcess.getName()
);
- final ReflectionManager reflectionManager = mappings.getReflectionManager();
- InheritanceState superEntityState =
- InheritanceState.getSuperEntityInheritanceState(
- clazzToProcess, inheritanceStatePerClass, reflectionManager
- );
- PersistentClass superEntity = superEntityState != null ?
- mappings.getClass(
- superEntityState.clazz.getName()
- ) :
- null;
- if ( superEntity == null ) {
- //check if superclass is not a potential persistent class
- if ( inheritanceState.hasParents ) {
- throw new AssertionFailure(
- "Subclass has to be binded after it's mother class: "
- + superEntityState.clazz.getName()
- );
- }
- }
- bindQueries( annotatedClass, mappings );
- bindFilterDefs( annotatedClass, mappings );
- bindTypeDefs( annotatedClass, mappings );
- BinderHelper.bindAnyMetaDefs( annotatedClass, mappings );
+ PersistentClass superEntity = getSuperEntity(clazzToProcess, inheritanceStatePerClass,
mappings, inheritanceState);
+
+ bindQueries( clazzToProcess, mappings );
+ bindFilterDefs( clazzToProcess, mappings );
+ bindTypeDefs( clazzToProcess, mappings );
+ BinderHelper.bindAnyMetaDefs( clazzToProcess, mappings );
+
String schema = "";
String table = ""; //might be no @Table annotation on the annotated class
String catalog = "";
- String discrimValue = null;
List<UniqueConstraintHolder> uniqueConstraints = new
ArrayList<UniqueConstraintHolder>();
- Ejb3DiscriminatorColumn discriminatorColumn = null;
- Ejb3JoinColumn[] inheritanceJoinedColumns = null;
-
- if ( annotatedClass.isAnnotationPresent( javax.persistence.Table.class ) ) {
- javax.persistence.Table tabAnn = annotatedClass.getAnnotation(
javax.persistence.Table.class );
+ if ( clazzToProcess.isAnnotationPresent( javax.persistence.Table.class ) ) {
+ javax.persistence.Table tabAnn = clazzToProcess.getAnnotation(
javax.persistence.Table.class );
table = tabAnn.name();
schema = tabAnn.schema();
catalog = tabAnn.catalog();
uniqueConstraints = TableBinder.buildUniqueConstraintHolders(
tabAnn.uniqueConstraints() );
}
- final boolean hasJoinedColumns = inheritanceState.hasParents
- && InheritanceType.JOINED.equals( inheritanceState.type );
- if ( hasJoinedColumns ) {
- //@Inheritance(JOINED) subclass need to link back to the super entity
- PrimaryKeyJoinColumns jcsAnn = annotatedClass.getAnnotation(
PrimaryKeyJoinColumns.class );
- boolean explicitInheritanceJoinedColumns = jcsAnn != null &&
jcsAnn.value().length != 0;
- if ( explicitInheritanceJoinedColumns ) {
- int nbrOfInhJoinedColumns = jcsAnn.value().length;
- PrimaryKeyJoinColumn jcAnn;
- inheritanceJoinedColumns = new Ejb3JoinColumn[nbrOfInhJoinedColumns];
- for (int colIndex = 0; colIndex < nbrOfInhJoinedColumns; colIndex++) {
- jcAnn = jcsAnn.value()[colIndex];
- inheritanceJoinedColumns[colIndex] = Ejb3JoinColumn.buildJoinColumn(
- jcAnn, null, superEntity.getIdentifier(),
- (Map<String, Join>) null, (PropertyHolder) null, mappings
- );
- }
- }
- else {
- PrimaryKeyJoinColumn jcAnn = annotatedClass.getAnnotation( PrimaryKeyJoinColumn.class
);
- inheritanceJoinedColumns = new Ejb3JoinColumn[1];
- inheritanceJoinedColumns[0] = Ejb3JoinColumn.buildJoinColumn(
- jcAnn, null, superEntity.getIdentifier(),
- (Map<String, Join>) null, (PropertyHolder) null, mappings
- );
- }
- log.debug( "Subclass joined column(s) created" );
- }
- else {
- if ( annotatedClass.isAnnotationPresent( javax.persistence.PrimaryKeyJoinColumns.class
)
- || annotatedClass.isAnnotationPresent( javax.persistence.PrimaryKeyJoinColumn.class
) ) {
- log.warn( "Root entity should not hold an PrimaryKeyJoinColum(s), will be
ignored" );
- }
- }
- if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.type ) ) {
- javax.persistence.DiscriminatorColumn discAnn = annotatedClass.getAnnotation(
+ Ejb3JoinColumn[] inheritanceJoinedColumns = makeInheritanceJoinColumns( clazzToProcess,
mappings, inheritanceState, superEntity );
+ Ejb3DiscriminatorColumn discriminatorColumn = null;
+ String discrimValue = null;
+ if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
+ javax.persistence.DiscriminatorColumn discAnn = clazzToProcess.getAnnotation(
javax.persistence.DiscriminatorColumn.class
);
DiscriminatorType discriminatorType = discAnn != null ?
discAnn.discriminatorType() :
DiscriminatorType.STRING;
- org.hibernate.annotations.DiscriminatorFormula discFormulaAnn =
annotatedClass.getAnnotation(
+ org.hibernate.annotations.DiscriminatorFormula discFormulaAnn =
clazzToProcess.getAnnotation(
org.hibernate.annotations.DiscriminatorFormula.class
);
- if ( !inheritanceState.hasParents ) {
+ if ( !inheritanceState.hasParents() ) {
discriminatorColumn = Ejb3DiscriminatorColumn.buildDiscriminatorColumn(
discriminatorType, discAnn, discFormulaAnn, mappings
);
}
- if ( discAnn != null && inheritanceState.hasParents ) {
+ if ( discAnn != null && inheritanceState.hasParents() ) {
log.warn(
"Discriminator column has to be defined in the root entity, it will be ignored
in subclass: {}",
clazzToProcess.getName()
);
}
- discrimValue = annotatedClass.isAnnotationPresent( DiscriminatorValue.class ) ?
- annotatedClass.getAnnotation( DiscriminatorValue.class ).value() :
+
+ discrimValue = clazzToProcess.isAnnotationPresent( DiscriminatorValue.class ) ?
+ clazzToProcess.getAnnotation( DiscriminatorValue.class ).value() :
null;
}
- //we now know what kind of persistent entity it is
- PersistentClass persistentClass;
- //create persistent class
- if ( !inheritanceState.hasParents ) {
- persistentClass = new RootClass();
- }
- else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.type ) ) {
- persistentClass = new SingleTableSubclass( superEntity );
- }
- else if ( InheritanceType.JOINED.equals( inheritanceState.type ) ) {
- persistentClass = new JoinedSubclass( superEntity );
- }
- else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.type ) ) {
- persistentClass = new UnionSubclass( superEntity );
- }
- else {
- throw new AssertionFailure( "Unknown inheritance type: " +
inheritanceState.type );
- }
- Proxy proxyAnn = annotatedClass.getAnnotation( Proxy.class );
- BatchSize sizeAnn = annotatedClass.getAnnotation( BatchSize.class );
- Where whereAnn = annotatedClass.getAnnotation( Where.class );
- Entity entityAnn = annotatedClass.getAnnotation( Entity.class );
- org.hibernate.annotations.Entity hibEntityAnn = annotatedClass.getAnnotation(
+ PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity
);
+
+ Proxy proxyAnn = clazzToProcess.getAnnotation( Proxy.class );
+ BatchSize sizeAnn = clazzToProcess.getAnnotation( BatchSize.class );
+ Where whereAnn = clazzToProcess.getAnnotation( Where.class );
+ Entity entityAnn = clazzToProcess.getAnnotation( Entity.class );
+ org.hibernate.annotations.Entity hibEntityAnn = clazzToProcess.getAnnotation(
org.hibernate.annotations.Entity.class
);
- org.hibernate.annotations.Cache cacheAnn = annotatedClass.getAnnotation(
+ org.hibernate.annotations.Cache cacheAnn = clazzToProcess.getAnnotation(
org.hibernate.annotations.Cache.class
);
EntityBinder entityBinder = new EntityBinder(
@@ -598,14 +518,14 @@
entityBinder.setInheritanceState( inheritanceState );
//Filters are not allowed on subclasses
- if ( !inheritanceState.hasParents ) {
+ if ( !inheritanceState.hasParents() ) {
bindFilters(clazzToProcess, entityBinder, mappings);
}
entityBinder.bindEntity();
if ( inheritanceState.hasTable() ) {
- Check checkAnn = annotatedClass.getAnnotation( Check.class );
+ Check checkAnn = clazzToProcess.getAnnotation( Check.class );
String constraints = checkAnn == null ?
null :
checkAnn.constraints();
@@ -617,32 +537,29 @@
);
}
else {
- if ( annotatedClass.isAnnotationPresent( Table.class ) ) {
+ if ( clazzToProcess.isAnnotationPresent( Table.class ) ) {
log.warn( "Illegal use of @Table in a subclass of a SINGLE_TABLE hierarchy:
" + clazzToProcess
.getName() );
}
}
-// Map<String, Column[]> columnOverride =
PropertyHolderBuilder.buildHierarchyColumnOverride(
-// clazzToProcess,
-// persistentClass.getClassName()
-// );
+
PropertyHolder propertyHolder = PropertyHolderBuilder.buildPropertyHolder(
clazzToProcess,
persistentClass,
entityBinder, mappings, inheritanceStatePerClass
);
- javax.persistence.SecondaryTable secTabAnn = annotatedClass.getAnnotation(
+ javax.persistence.SecondaryTable secTabAnn = clazzToProcess.getAnnotation(
javax.persistence.SecondaryTable.class
);
- javax.persistence.SecondaryTables secTabsAnn = annotatedClass.getAnnotation(
+ javax.persistence.SecondaryTables secTabsAnn = clazzToProcess.getAnnotation(
javax.persistence.SecondaryTables.class
);
entityBinder.firstLevelSecondaryTablesBinding( secTabAnn, secTabsAnn );
- OnDelete onDeleteAnn = annotatedClass.getAnnotation( OnDelete.class );
+ OnDelete onDeleteAnn = clazzToProcess.getAnnotation( OnDelete.class );
boolean onDeleteAppropriate = false;
- if ( InheritanceType.JOINED.equals( inheritanceState.type ) &&
inheritanceState.hasParents ) {
+ if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) &&
inheritanceState.hasParents() ) {
onDeleteAppropriate = true;
final JoinedSubclass jsc = (JoinedSubclass) persistentClass;
if ( persistentClass.getEntityPersisterClass() == null ) {
@@ -650,7 +567,7 @@
}
SimpleValue key = new DependantValue( jsc.getTable(), jsc.getIdentifier() );
jsc.setKey( key );
- ForeignKey fk = annotatedClass.getAnnotation( ForeignKey.class );
+ ForeignKey fk = clazzToProcess.getAnnotation( ForeignKey.class );
if ( fk != null && !BinderHelper.isDefault( fk.name() ) ) {
key.setForeignKeyName( fk.name() );
}
@@ -666,14 +583,14 @@
mappings.addSecondPass( new CreateKeySecondPass( jsc ) );
}
- else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.type ) ) {
- if ( inheritanceState.hasParents ) {
+ else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
+ if ( inheritanceState.hasParents() ) {
if ( persistentClass.getEntityPersisterClass() == null ) {
persistentClass.getRootClass().setEntityPersisterClass(
SingleTableEntityPersister.class );
}
}
else {
- if ( inheritanceState.hasSons || !discriminatorColumn.isImplicit() ) {
+ if ( inheritanceState.hasSiblings() || !discriminatorColumn.isImplicit() ) {
//need a discriminator column
bindDiscriminatorToPersistentClass(
(RootClass) persistentClass,
@@ -685,8 +602,8 @@
}
}
}
- else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.type ) ) {
- if ( inheritanceState.hasParents ) {
+ else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
+ if ( inheritanceState.hasParents() ) {
if ( persistentClass.getEntityPersisterClass() == null ) {
persistentClass.getRootClass().setEntityPersisterClass(
UnionSubclassEntityPersister.class );
}
@@ -699,7 +616,7 @@
}
//try to find class level generators
- HashMap<String, IdGenerator> classGenerators = buildLocalGenerators(
annotatedClass, mappings );
+ HashMap<String, IdGenerator> classGenerators = buildLocalGenerators(
clazzToProcess, mappings );
// check properties
List<PropertyData> elements =
@@ -709,30 +626,29 @@
if ( elements == null ) {
throw new AnnotationException( "No identifier specified for entity: " +
propertyHolder.getEntityName() );
}
- final boolean subclassAndSingleTableStrategy = inheritanceState.type ==
InheritanceType.SINGLE_TABLE
- && inheritanceState.hasParents;
+ final boolean subclassAndSingleTableStrategy = inheritanceState.getType() ==
InheritanceType.SINGLE_TABLE
+ && inheritanceState.hasParents();
//process idclass if any
Set<String> idProperties = new HashSet<String>();
IdClass idClass = null;
XClass current = null;
- if ( !inheritanceState.hasParents ) {
+ if ( !inheritanceState.hasParents() ) {
//look for idClass
- current = inheritanceState.clazz;
InheritanceState state = inheritanceState;
do {
- current = state.clazz;
+ current = state.getClazz();
if ( current.isAnnotationPresent( IdClass.class ) ) {
idClass = current.getAnnotation( IdClass.class );
break;
}
state = InheritanceState.getSuperclassInheritanceState(
- current, inheritanceStatePerClass, reflectionManager
+ current, inheritanceStatePerClass, mappings.getReflectionManager()
);
}
while ( state != null );
}
if ( idClass != null ) {
- XClass compositeClass = reflectionManager.toXClass( idClass.value() );
+ XClass compositeClass = mappings.getReflectionManager().toXClass( idClass.value() );
boolean isComponent = true;
boolean propertyAnnotated = entityBinder.isPropertyAnnotated( compositeClass );
String propertyAccessor = entityBinder.getPropertyAccessor( compositeClass );
@@ -837,7 +753,7 @@
);
}
- if ( !inheritanceState.hasParents ) {
+ if ( !inheritanceState.hasParents() ) {
final RootClass rootClass = (RootClass) persistentClass;
mappings.addSecondPass( new CreateKeySecondPass( rootClass ) );
}
@@ -848,14 +764,121 @@
mappings.addClass( persistentClass );
//Process secondary tables and complementary definitions (ie o.h.a.Table)
- mappings.addSecondPass( new SecondaryTableSecondPass( entityBinder, propertyHolder,
annotatedClass ) );
+ mappings.addSecondPass( new SecondaryTableSecondPass( entityBinder, propertyHolder,
clazzToProcess ) );
//add process complementary Table definition (index & all)
- entityBinder.processComplementaryTableDefinitions( annotatedClass.getAnnotation(
org.hibernate.annotations.Table.class ) );
- entityBinder.processComplementaryTableDefinitions( annotatedClass.getAnnotation(
org.hibernate.annotations.Tables.class ) );
+ entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation(
org.hibernate.annotations.Table.class ) );
+ entityBinder.processComplementaryTableDefinitions( clazzToProcess.getAnnotation(
org.hibernate.annotations.Tables.class ) );
}
+ private static PersistentClass makePersistentClass(InheritanceState inheritanceState,
PersistentClass superEntity) {
+ //we now know what kind of persistent entity it is
+ PersistentClass persistentClass;
+ //create persistent class
+ if ( !inheritanceState.hasParents() ) {
+ persistentClass = new RootClass();
+ }
+ else if ( InheritanceType.SINGLE_TABLE.equals( inheritanceState.getType() ) ) {
+ persistentClass = new SingleTableSubclass( superEntity );
+ }
+ else if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) ) {
+ persistentClass = new JoinedSubclass( superEntity );
+ }
+ else if ( InheritanceType.TABLE_PER_CLASS.equals( inheritanceState.getType() ) ) {
+ persistentClass = new UnionSubclass( superEntity );
+ }
+ else {
+ throw new AssertionFailure( "Unknown inheritance type: " +
inheritanceState.getType() );
+ }
+ return persistentClass;
+ }
+
+ private static Ejb3JoinColumn[] makeInheritanceJoinColumns(XClass clazzToProcess,
ExtendedMappings mappings, InheritanceState inheritanceState, PersistentClass superEntity)
{
+ Ejb3JoinColumn[] inheritanceJoinedColumns = null;
+ final boolean hasJoinedColumns = inheritanceState.hasParents()
+ && InheritanceType.JOINED.equals( inheritanceState.getType() );
+ if ( hasJoinedColumns ) {
+ //@Inheritance(JOINED) subclass need to link back to the super entity
+ PrimaryKeyJoinColumns jcsAnn = clazzToProcess.getAnnotation(
PrimaryKeyJoinColumns.class );
+ boolean explicitInheritanceJoinedColumns = jcsAnn != null &&
jcsAnn.value().length != 0;
+ if ( explicitInheritanceJoinedColumns ) {
+ int nbrOfInhJoinedColumns = jcsAnn.value().length;
+ PrimaryKeyJoinColumn jcAnn;
+ inheritanceJoinedColumns = new Ejb3JoinColumn[nbrOfInhJoinedColumns];
+ for (int colIndex = 0; colIndex < nbrOfInhJoinedColumns; colIndex++) {
+ jcAnn = jcsAnn.value()[colIndex];
+ inheritanceJoinedColumns[colIndex] = Ejb3JoinColumn.buildJoinColumn(
+ jcAnn, null, superEntity.getIdentifier(),
+ ( Map<String, Join> ) null, ( PropertyHolder ) null, mappings
+ );
+ }
+ }
+ else {
+ PrimaryKeyJoinColumn jcAnn = clazzToProcess.getAnnotation( PrimaryKeyJoinColumn.class
);
+ inheritanceJoinedColumns = new Ejb3JoinColumn[1];
+ inheritanceJoinedColumns[0] = Ejb3JoinColumn.buildJoinColumn(
+ jcAnn, null, superEntity.getIdentifier(),
+ (Map<String, Join>) null, (PropertyHolder) null, mappings
+ );
+ }
+ log.debug( "Subclass joined column(s) created" );
+ }
+ else {
+ if ( clazzToProcess.isAnnotationPresent( PrimaryKeyJoinColumns.class )
+ || clazzToProcess.isAnnotationPresent( PrimaryKeyJoinColumn.class ) ) {
+ log.warn( "Root entity should not hold an PrimaryKeyJoinColum(s), will be
ignored" );
+ }
+ }
+ return inheritanceJoinedColumns;
+ }
+
+ private static PersistentClass getSuperEntity(XClass clazzToProcess, Map<XClass,
InheritanceState> inheritanceStatePerClass, ExtendedMappings mappings, InheritanceState
inheritanceState) {
+ final ReflectionManager reflectionManager = mappings.getReflectionManager();
+ InheritanceState superEntityState =
+ InheritanceState.getInheritanceStateOfSuperEntity(
+ clazzToProcess, inheritanceStatePerClass, reflectionManager
+ );
+ PersistentClass superEntity = superEntityState != null ?
+ mappings.getClass(
+ superEntityState.getClazz().getName()
+ ) :
+ null;
+ if ( superEntity == null ) {
+ //check if superclass is not a potential persistent class
+ if ( inheritanceState.hasParents() ) {
+ throw new AssertionFailure(
+ "Subclass has to be binded after it's mother class: "
+ + superEntityState.getClazz().getName()
+ );
+ }
+ }
+ return superEntity;
+ }
+
+ private static boolean isEntityClassType(XClass clazzToProcess, AnnotatedClassType
classType) {
+ if ( AnnotatedClassType.EMBEDDABLE_SUPERCLASS.equals( classType ) //will be processed
by their subentities
+ || AnnotatedClassType.NONE.equals( classType ) //to be ignored
+ || AnnotatedClassType.EMBEDDABLE.equals( classType ) //allow embeddable element
declaration
+ ) {
+ if ( AnnotatedClassType.NONE.equals( classType )
+ && clazzToProcess.isAnnotationPresent(
org.hibernate.annotations.Entity.class ) ) {
+ log.warn( "Class annotated @org.hibernate.annotations.Entity but not
javax.persistence.Entity "
+ + "(most likely a user error): {}", clazzToProcess.getName() );
+ }
+ return false;
+ }
+
+ if ( !classType.equals( AnnotatedClassType.ENTITY ) ) {
+ throw new AnnotationException(
+ "Annotated class should have a @javax.persistence.Entity,
@javax.persistence.Embeddable or @javax.persistence.EmbeddedSuperclass annotation: "
+ clazzToProcess
+ .getName()
+ );
+ }
+
+ return true;
+ }
+
/**
* Get the annotated elements
* Guess the annotated element from @Id or @EmbeddedId presence
@@ -874,19 +897,19 @@
int deep = classesToProcess.size();
boolean hasIdentifier = false;
- assert !inheritanceState.isEmbeddableSuperclass;
+ assert !inheritanceState.isEmbeddableSuperclass();
Boolean isExplicitPropertyAnnotated = null;
String explicitAccessType;
- if ( inheritanceState.hasParents ) {
+ if ( inheritanceState.hasParents() ) {
InheritanceState superEntityState =
- InheritanceState.getSuperEntityInheritanceState(
+ InheritanceState.getInheritanceStateOfSuperEntity(
clazzToProcess, inheritanceStatePerClass, mappings.getReflectionManager()
);
isExplicitPropertyAnnotated = superEntityState != null ?
- superEntityState.isPropertyAnnotated :
+ superEntityState.isPropertyAnnotated() :
null;
explicitAccessType = superEntityState != null ?
- superEntityState.accessType :
+ superEntityState.getAccessType() :
null;
}
else {
@@ -928,7 +951,7 @@
exceptionWhileWalkingElements = e;
}
- if ( !hasIdentifier && !inheritanceState.hasParents ) {
+ if ( !hasIdentifier && !inheritanceState.hasParents() ) {
if ( isExplicitPropertyAnnotated != null ) {
//the original exception is legitimate
if ( exceptionWhileWalkingElements != null) throw exceptionWhileWalkingElements;
@@ -953,9 +976,9 @@
//TODO set the access type here?
entityBinder.setPropertyAnnotated( isPropertyAnnotated );
entityBinder.setPropertyAccessor( accessType );
- inheritanceState.isPropertyAnnotated = isPropertyAnnotated;
- inheritanceState.accessType = accessType;
- return hasIdentifier || inheritanceState.hasParents ?
+ inheritanceState.setPropertyAnnotated( isPropertyAnnotated );
+ inheritanceState.setAccessType( accessType );
+ return hasIdentifier || inheritanceState.hasParents() ?
elements :
null;
}
@@ -983,16 +1006,16 @@
currentClassInHierarchy = superClass;
}
- while ( superclassState != null && superclassState.isEmbeddableSuperclass );
+ 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);
+ InheritanceState.getInheritanceStateOfSuperEntity(annotatedClass,
inheritanceStatePerClass, reflectionManager);
PersistentClass superEntity =
superEntityState != null ?
- mappings.getClass( superEntityState.clazz.getName() ) :
+ mappings.getClass( superEntityState.getClazz().getName() ) :
null;
final int lastMappedSuperclass = classesToProcess.size() - 1;
for ( int index = 0 ; index < lastMappedSuperclass ; index++ ) {
@@ -1139,7 +1162,7 @@
String localPropertyAccessor = access != null ?
access.value() :
null;
- String accessType = null;
+ String accessType;
if ( "property".equals( localPropertyAccessor ) || "field".equals(
localPropertyAccessor ) ) {
accessType = localPropertyAccessor;
}
@@ -1579,8 +1602,6 @@
}
Cascade hibernateCascade = property.getAnnotation( Cascade.class );
- NotFound notFound = property.getAnnotation( NotFound.class );
- boolean ignoreNotFound = notFound != null && notFound.action().equals(
NotFoundAction.IGNORE );
OnDelete onDeleteAnn = property.getAnnotation( OnDelete.class );
boolean onDeleteCascade = onDeleteAnn != null &&
OnDeleteAction.CASCADE.equals( onDeleteAnn.action() );
JoinTable assocTable = property.getAnnotation( JoinTable.class );
@@ -1654,7 +1675,7 @@
collectionBinder.setMappings( mappings );
collectionBinder.setPropertyAccessorName( inferredData.getDefaultAccess() );
- Ejb3Column[] elementColumns = null;
+ Ejb3Column[] elementColumns;
PropertyData virtualProperty = new WrappedInferredData( inferredData,
"element" );
if ( property.isAnnotationPresent( Column.class ) || property.isAnnotationPresent(
Formula.class
@@ -1860,7 +1881,7 @@
}
else {
//define whether the type is a component or not
- boolean isComponent = false;
+ boolean isComponent;
Embeddable embeddableAnn = returnedClass.getAnnotation( Embeddable.class );
Embedded embeddedAnn = property.getAnnotation( Embedded.class );
isComponent = embeddedAnn != null || embeddableAnn != null;
@@ -2185,9 +2206,7 @@
);
}
RootClass rootClass = (RootClass) persistentClass;
- String persistentClassName = rootClass == null ?
- null :
- rootClass.getClassName();
+ String persistentClassName = rootClass.getClassName();
SimpleValue id;
if ( isComposite ) {
id = fillComponent(
@@ -2620,6 +2639,14 @@
return mappings.getReflectionManager().equals( clazz, void.class );
}
+ /**
+ * For the mapped entities build some temporary data-structure containing information
about the
+ * inheritance status of a class.
+ *
+ * @param orderedClasses Order list of all annotated entities and their mapped
superclasses
+ * @param reflectionManager Reference to the reflection manager (commons-annotations)
+ * @return A map of {@code InheritanceState}s keyed against their {@code XClass}.
+ */
public static Map<XClass, InheritanceState> buildInheritanceStates(
List<XClass> orderedClasses, ReflectionManager reflectionManager
) {
@@ -2635,22 +2662,22 @@
if ( superclassState != null ) {
//the classes are ordered thus preventing an NPE
//FIXME if an entity has subclasses annotated @MappedSperclass wo sub @Entity this is
wrong
- superclassState.hasSons = true;
- InheritanceState superEntityState = InheritanceState.getSuperEntityInheritanceState(
+ superclassState.setHasSiblings( true );
+ InheritanceState superEntityState =
InheritanceState.getInheritanceStateOfSuperEntity(
clazz, inheritanceStatePerClass,
reflectionManager
);
- state.hasParents = superEntityState != null;
- final boolean nonDefault = state.type != null &&
!InheritanceType.SINGLE_TABLE.equals( state.type );
- if ( superclassState.type != null ) {
- final boolean mixingStrategy = state.type != null && !state.type.equals(
superclassState.type );
+ state.setHasParents( superEntityState != null );
+ final boolean nonDefault = state.getType() != null &&
!InheritanceType.SINGLE_TABLE.equals( state.getType() );
+ if ( superclassState.getType() != null ) {
+ final boolean mixingStrategy = state.getType() != null &&
!state.getType().equals( superclassState.getType() );
if ( nonDefault && mixingStrategy ) {
log.warn(
"Mixing inheritance strategy in a entity hierarchy is not allowed, ignoring
sub strategy in: {}",
clazz.getName()
);
}
- state.type = superclassState.type;
+ state.setType( superclassState.getType() );
}
}
inheritanceStatePerClass.put( clazz, state );
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/AnnotationConfiguration.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -123,7 +123,6 @@
private Set<String> defaultNamedGenerators;
private Map<String, Properties> generatorTables;
private Map<Table, List<UniqueConstraintHolder>>
uniqueConstraintHoldersByTable;
-// private Map<Table, List<String[]>> tableUniqueConstraints;
private Map<String, String> mappedByResolver;
private Map<String, String> propertyRefResolver;
private Map<String, AnyMetaDef> anyMetaDefs;
@@ -146,10 +145,30 @@
super( sf );
}
+ /**
+ * Takes the list of entities annotated with {@code @Entity} or {@code
@MappedSuperclass} and returns them in an
+ * ordered list.
+ *
+ * @param original The list of all entities annotated with {@code @Entity} or {@code
@MappedSuperclass}
+ * @return Ordered list of entities including superclasses for entities which have any.
Class hierachies are
+ * listed bottom up (starting from the top level base class). There is no indication in
the list when a new class
+ * (hierarchy) starts.
+ */
protected List<XClass> orderAndFillHierarchy(List<XClass> original) {
- //TODO remove embeddable
List<XClass> copy = new ArrayList<XClass>( original );
- //for each class, copy all the relevant hierarchy
+ insertMappedSuperclasses( original, copy );
+
+ // order the hierarchy
+ List<XClass> workingCopy = new ArrayList<XClass>( copy );
+ List<XClass> newList = new ArrayList<XClass>( copy.size() );
+ while ( workingCopy.size() > 0 ) {
+ XClass clazz = workingCopy.get( 0 );
+ orderHierarchy( workingCopy, newList, copy, clazz );
+ }
+ return newList;
+ }
+
+ private void insertMappedSuperclasses(List<XClass> original, List<XClass>
copy) {
for ( XClass clazz : original ) {
XClass superClass = clazz.getSuperclass();
while ( superClass != null && !reflectionManager.equals( superClass,
Object.class ) && !copy.contains(
@@ -162,13 +181,6 @@
superClass = superClass.getSuperclass();
}
}
- List<XClass> workingCopy = new ArrayList<XClass>( copy );
- List<XClass> newList = new ArrayList<XClass>( copy.size() );
- while ( workingCopy.size() > 0 ) {
- XClass clazz = workingCopy.get( 0 );
- orderHierarchy( workingCopy, newList, copy, clazz );
- }
- return newList;
}
private void orderHierarchy(List<XClass> copy, List<XClass> newList,
List<XClass> original, XClass clazz) {
@@ -598,6 +610,7 @@
orderedClasses, reflectionManager
);
ExtendedMappings mappings = createExtendedMappings();
+
for ( XClass clazz : orderedClasses ) {
//todo use the same extended mapping
AnnotationBinder.bindClass( clazz, inheritanceStatePerClass, mappings );
@@ -1166,20 +1179,6 @@
}
protected class ExtendedMappingsImpl extends MappingsImpl implements ExtendedMappings {
-// private final Map<String, IdGenerator> namedGenerators;
-// private final Map<String, Map<String, Join>> joins;
-// private final Map<String, AnnotatedClassType> classTypes;
-// private final Map<String, Properties> generatorTables;
-// private final Map<Table, List<String[]>> tableUniqueConstraints;
-// private final Map<String, String> mappedByResolver;
-// private final Map<String, String> propertyRefResolver;
-// private final ReflectionManager reflectionManager;
-// private final Set<String> defaultNamedQueryNames;
-// private final Set<String> defaultNamedNativeQueryNames;
-// private final Set<String> defaultSqlResulSetMappingNames;
-// private final Set<String> defaultNamedGenerators;
-// private final Map<String, AnyMetaDef> anyMetaDefs;
-
public void addDefaultGenerator(IdGenerator generator) {
this.addGenerator( generator );
defaultNamedGenerators.add( generator.getName() );
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java
===================================================================
--- core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2009-12-11
16:44:23 UTC (rev 18210)
+++ core/trunk/annotations/src/main/java/org/hibernate/cfg/BinderHelper.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -591,7 +591,7 @@
"Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
);
}
- if ( inheritanceState.isEmbeddableSuperclass ) {
+ if ( inheritanceState.isEmbeddableSuperclass() ) {
retrieve = true;
}
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/ClassPropertyHolder.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -113,7 +113,7 @@
"Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
);
}
- if ( inheritanceState.isEmbeddableSuperclass ) {
+ if ( inheritanceState.isEmbeddableSuperclass() ) {
persistentClass.addMappedsuperclassProperty(prop);
addPropertyToMappedSuperclass( prop, declaringClass );
}
@@ -141,7 +141,7 @@
"Declaring class is not found in the inheritance state hierarchy: " +
declaringClass
);
}
- if ( inheritanceState.isEmbeddableSuperclass ) {
+ if ( inheritanceState.isEmbeddableSuperclass() ) {
join.addMappedsuperclassProperty(prop);
addPropertyToMappedSuperclass( prop, declaringClass );
}
Modified: core/trunk/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/InheritanceState.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -33,56 +33,58 @@
import org.hibernate.annotations.common.reflection.XClass;
/**
- * Some extra data to the inheritance position of a class
+ * Some extra data to the inheritance position of a class.
*
* @author Emmanuel Bernard
*/
public class InheritanceState {
public InheritanceState(XClass clazz) {
- this.clazz = clazz;
+ this.setClazz( clazz );
extractInheritanceType();
}
- public XClass clazz;
+ private XClass clazz;
+
/**
- * has son either mappedsuperclass son or entity son
+ * Has sibling (either mappedsuperclass entity)
*/
- public boolean hasSons = false;
+ private boolean hasSiblings = false;
+
/**
* a mother entity is available
*/
- public boolean hasParents = false;
- public InheritanceType type;
- public boolean isEmbeddableSuperclass = false;
+ private boolean hasParents = false;
+ private InheritanceType type;
+ private boolean isEmbeddableSuperclass = false;
/**
* only defined on embedded superclasses
*/
- public String accessType = null;
- public Boolean isPropertyAnnotated;
+ private String accessType = null;
+ private Boolean isPropertyAnnotated;
private void extractInheritanceType() {
- XAnnotatedElement element = clazz;
+ XAnnotatedElement element = getClazz();
Inheritance inhAnn = element.getAnnotation( Inheritance.class );
MappedSuperclass mappedSuperClass = element.getAnnotation( MappedSuperclass.class );
if ( mappedSuperClass != null ) {
- isEmbeddableSuperclass = true;
- type = inhAnn == null ? null : inhAnn.strategy();
+ setEmbeddableSuperclass( true );
+ setType( inhAnn == null ? null : inhAnn.strategy() );
}
else {
- type = inhAnn == null ? InheritanceType.SINGLE_TABLE : inhAnn.strategy();
+ setType( inhAnn == null ? InheritanceType.SINGLE_TABLE : inhAnn.strategy() );
}
}
boolean hasTable() {
- return !hasParents || !InheritanceType.SINGLE_TABLE.equals( type );
+ return !hasParents() || !InheritanceType.SINGLE_TABLE.equals( getType() );
}
boolean hasDenormalizedTable() {
- return hasParents && InheritanceType.TABLE_PER_CLASS.equals( type );
+ return hasParents() && InheritanceType.TABLE_PER_CLASS.equals( getType() );
}
- public static InheritanceState getSuperEntityInheritanceState(
+ public static InheritanceState getInheritanceStateOfSuperEntity(
XClass clazz, Map<XClass, InheritanceState> states,
ReflectionManager reflectionManager
) {
@@ -90,7 +92,9 @@
do {
superclass = superclass.getSuperclass();
InheritanceState currentState = states.get( superclass );
- if ( currentState != null && !currentState.isEmbeddableSuperclass ) return
currentState;
+ if ( currentState != null && !currentState.isEmbeddableSuperclass() ) {
+ return currentState;
+ }
}
while ( superclass != null && !reflectionManager.equals( superclass,
Object.class ) );
return null;
@@ -109,4 +113,60 @@
while ( superclass != null && !reflectionManager.equals( superclass,
Object.class ) );
return null;
}
+
+ public XClass getClazz() {
+ return clazz;
+ }
+
+ public void setClazz(XClass clazz) {
+ this.clazz = clazz;
+ }
+
+ public boolean hasSiblings() {
+ return hasSiblings;
+ }
+
+ public void setHasSiblings(boolean hasSiblings) {
+ this.hasSiblings = hasSiblings;
+ }
+
+ public boolean hasParents() {
+ return hasParents;
+ }
+
+ public void setHasParents(boolean hasParents) {
+ this.hasParents = hasParents;
+ }
+
+ public InheritanceType getType() {
+ return type;
+ }
+
+ public void setType(InheritanceType type) {
+ this.type = type;
+ }
+
+ public boolean isEmbeddableSuperclass() {
+ return isEmbeddableSuperclass;
+ }
+
+ public void setEmbeddableSuperclass(boolean embeddableSuperclass) {
+ isEmbeddableSuperclass = embeddableSuperclass;
+ }
+
+ public String getAccessType() {
+ return accessType;
+ }
+
+ public void setAccessType(String accessType) {
+ this.accessType = accessType;
+ }
+
+ public Boolean isPropertyAnnotated() {
+ return isPropertyAnnotated;
+ }
+
+ public void setPropertyAnnotated(Boolean propertyAnnotated) {
+ isPropertyAnnotated = propertyAnnotated;
+ }
}
Modified:
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java
===================================================================
---
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -294,7 +294,7 @@
persistentClass.addTuplizer( mode, tuplizer.impl().getName() );
}
- if ( !inheritanceState.hasParents ) {
+ if ( !inheritanceState.hasParents() ) {
for ( Map.Entry<String, String> filter : filters.entrySet() ) {
String filterName = filter.getKey();
String cond = filter.getValue();
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/access/AccessTest.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/access/AccessTest.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/access/AccessTest.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -9,7 +9,7 @@
* @author Emmanuel Bernard
*/
public class AccessTest extends TestCase {
-
+
public void testSuperclassOverriding() throws Exception {
Furniture fur = new Furniture();
fur.setColor( "Black" );
@@ -21,7 +21,7 @@
tx.commit();
s.clear();
tx = s.beginTransaction();
- fur = (Furniture) s.get( Furniture.class, fur.getId() );
+ fur = ( Furniture ) s.get( Furniture.class, fur.getId() );
assertFalse( fur.isAlive );
assertNotNull( fur.getColor() );
s.delete( fur );
@@ -38,7 +38,7 @@
tx.commit();
s.clear();
tx = s.beginTransaction();
- fur = (Furniture) s.get( Furniture.class, fur.getId() );
+ fur = ( Furniture ) s.get( Furniture.class, fur.getId() );
assertNotNull( fur.getGod() );
s.delete( fur );
tx.commit();
@@ -54,12 +54,11 @@
tx.commit();
s.clear();
tx = s.beginTransaction();
- fur = (Furniture) s.get( Furniture.class, fur.getId() );
+ fur = ( Furniture ) s.get( Furniture.class, fur.getId() );
assertEquals( 5, fur.weight );
s.delete( fur );
tx.commit();
s.close();
-
}
public void testNonOverridenSubclass() throws Exception {
@@ -71,12 +70,11 @@
tx.commit();
s.clear();
tx = s.beginTransaction();
- chair = (Chair) s.get( Chair.class, chair.getId() );
+ chair = ( Chair ) s.get( Chair.class, chair.getId() );
assertNull( chair.getPillow() );
s.delete( chair );
tx.commit();
s.close();
-
}
public void testOverridenSubclass() throws Exception {
@@ -89,13 +87,12 @@
tx.commit();
s.clear();
tx = s.beginTransaction();
- bed = (BigBed) s.get( BigBed.class, bed.getId() );
+ bed = ( BigBed ) s.get( BigBed.class, bed.getId() );
assertEquals( 5, bed.size );
assertNull( bed.getQuality() );
s.delete( bed );
tx.commit();
s.close();
-
}
public void testFieldsOverriding() throws Exception {
@@ -107,22 +104,21 @@
tx.commit();
s.clear();
tx = s.beginTransaction();
- gs = (Gardenshed) s.get( Gardenshed.class, gs.getId() );
+ gs = ( Gardenshed ) s.get( Gardenshed.class, gs.getId() );
assertEquals( 4, gs.floors );
assertEquals( 6, gs.getFloors() );
s.delete( gs );
tx.commit();
s.close();
-
}
protected Class[] getMappings() {
- return new Class[]{
+ return new Class[] {
Bed.class,
Chair.class,
Furniture.class,
BigBed.class,
- Gardenshed.class
+ Gardenshed.class,
};
}
}
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/access/Furniture.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/access/Furniture.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/access/Furniture.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -37,7 +37,6 @@
this.id = id;
}
-
@AccessType("property")
public long weight;
Modified:
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/embedded/Country.java
===================================================================
---
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/embedded/Country.java 2009-12-11
16:44:23 UTC (rev 18210)
+++
core/trunk/annotations/src/test/java/org/hibernate/test/annotations/embedded/Country.java 2009-12-11
19:14:01 UTC (rev 18211)
@@ -13,7 +13,6 @@
* @author Emmanuel Bernard
*/
@Embeddable
-//access = AccessType.PROPERTY)
@AccessType("property")
public class Country implements Serializable {
private String iso2;
@@ -35,5 +34,4 @@
public void setName(String name) {
this.name = name;
}
-
}