From e5da09cee023ea1fd67d491a9ae761fdf36cfd2f Mon Sep 17 00:00:00 2001 From: Hardy Ferentschik Date: Sun, 8 May 2011 01:04:16 +0200 Subject: [PATCH] HHH-6201 Introducing a Nonentity, refactoring ConfiguredClass to properly support binding of mapped superclasses and non entities --- .../EntityReferencingAttributeBinding.java | 7 +- .../domain/AbstractAttributeContainer.java | 2 +- .../hibernate/metamodel/domain/NonEntity.java | 42 ++++++++++++ .../metamodel/domain/TypeNature.java | 3 +- .../source/annotations/AnnotationBinder.java | 8 +-- .../source/annotations/ConfiguredClass.java | 68 +++++++++++-------- .../annotations/ConfiguredClassType.java | 34 ++++++++++ .../source/annotations/HibernateDotNames.java | 2 - 8 files changed, 126 insertions(+), 40 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/domain/NonEntity.java create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClassType.java diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityReferencingAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityReferencingAttributeBinding.java index c181fff4c3..11a0da1d4f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityReferencingAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/EntityReferencingAttributeBinding.java @@ -23,8 +23,6 @@ */ package org.hibernate.metamodel.binding; -import org.hibernate.metamodel.relational.Value; - /** * TODO : javadoc * @@ -32,9 +30,14 @@ import org.hibernate.metamodel.relational.Value; */ public interface EntityReferencingAttributeBinding extends AttributeBinding { boolean isReferenceResolved(); + boolean isPropertyReference(); + String getReferencedEntityName(); + String getReferencedAttributeName(); + EntityBinding getReferencedEntityBinding(); + void resolveReference(AttributeBinding attributeBinding); } \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java index 35a12e54b6..7cf8c90b08 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/AbstractAttributeContainer.java @@ -111,7 +111,7 @@ public abstract class AbstractAttributeContainer implements AttributeContainer, protected void addAttribute(Attribute attribute) { // todo : how to best "secure" this? if ( attributeMap.put( attribute.getName(), attribute ) != null ) { - throw new IllegalArgumentException( "Attrtibute with name [" + attribute.getName() + "] already registered" ); + throw new IllegalArgumentException( "Attribute with name [" + attribute.getName() + "] already registered" ); } attributeSet.add( attribute ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/NonEntity.java b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/NonEntity.java new file mode 100644 index 0000000000..198b7b28ff --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/NonEntity.java @@ -0,0 +1,42 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2010, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.domain; + +/** + * Models the concept class in the hierarchy with no persistent attributes. + * + * @author Hardy Ferentschik + */ +public class NonEntity extends AbstractAttributeContainer implements Hierarchical { + public NonEntity(String name, Hierarchical superType) { + super( name, superType ); + } + + /** + * {@inheritDoc} + */ + public TypeNature getNature() { + return TypeNature.NON_ENTITY; + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/TypeNature.java b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/TypeNature.java index 9c0c9fa318..09350d2a80 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/domain/TypeNature.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/domain/TypeNature.java @@ -32,7 +32,8 @@ public enum TypeNature { BASIC( "basic" ), COMPONENT( "component" ), ENTITY( "entity" ), - SUPERCLASS( "superclass" ); + SUPERCLASS( "superclass" ), + NON_ENTITY( "non-entity" ); private final String name; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java index 8469072196..7adc497b8b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/AnnotationBinder.java @@ -75,11 +75,9 @@ public class AnnotationBinder { // now we process each hierarchy one at the time for ( ConfiguredClassHierarchy hierarchy : hierarchies ) { - Iterator iter = hierarchy.iterator(); - while ( iter.hasNext() ) { - ConfiguredClass entity = iter.next(); - log.info( "Binding entity from annotated class: {}", entity.getName() ); - EntityBinder entityBinder = new EntityBinder( metadata, entity ); + for ( ConfiguredClass configuredClass : hierarchy ) { + log.info( "Binding entity from annotated class: {}", configuredClass.getName() ); + EntityBinder entityBinder = new EntityBinder( metadata, configuredClass ); entityBinder.bind(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClass.java index b8a1eb9133..cab31ba8aa 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClass.java @@ -75,10 +75,8 @@ public class ConfiguredClass { private final InheritanceType inheritanceType; private final boolean hasOwnTable; private final String primaryTableName; - //private final AnnotationInstance tableAnnotation; - private final boolean isMappedSuperClass; - private final boolean isEmbeddable; + private final ConfiguredClassType type; private final Map mappedAttributes; @@ -95,22 +93,11 @@ public class ConfiguredClass { this.inheritanceType = inheritanceType; this.clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( info.toString() ); - AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation( - classInfo, JPADotNames.MAPPED_SUPERCLASS - ); - isMappedSuperClass = mappedSuperClassAnnotation != null; + this.type = determineType(); + this.classAccessType = determineClassAccessType(); - AnnotationInstance embeddableAnnotation = JandexHelper.getSingleAnnotation( - classInfo, JPADotNames.MAPPED_SUPERCLASS - ); - isEmbeddable = embeddableAnnotation != null; - - // todo think about how exactly to handle embeddables regarding access type etc - - classAccessType = determineClassAccessType(); - - hasOwnTable = definesItsOwnTable(); - primaryTableName = determinePrimaryTableName(); + this.hasOwnTable = definesItsOwnTable(); + this.primaryTableName = determinePrimaryTableName(); List properties = collectMappedProperties( resolvedType ); // make sure the properties are ordered by property name @@ -119,7 +106,7 @@ public class ConfiguredClass { for ( MappedAttribute property : properties ) { tmpMap.put( property.getName(), property ); } - mappedAttributes = Collections.unmodifiableMap( tmpMap ); + this.mappedAttributes = Collections.unmodifiableMap( tmpMap ); } public String getName() { @@ -138,12 +125,8 @@ public class ConfiguredClass { return isRoot; } - public boolean isMappedSuperClass() { - return isMappedSuperClass; - } - - public boolean isEmbeddable() { - return isEmbeddable; + public ConfiguredClassType getType() { + return type; } public InheritanceType getInheritanceType() { @@ -170,8 +153,8 @@ public class ConfiguredClass { public String toString() { final StringBuilder sb = new StringBuilder(); sb.append( "ConfiguredClass" ); - sb.append( "{clazz=" ).append( clazz ); - sb.append( ", mappedAttributes=" ).append( mappedAttributes ); + sb.append( "{clazz=" ).append( clazz.getSimpleName() ); + sb.append( ", type=" ).append( type ); sb.append( ", classAccessType=" ).append( classAccessType ); sb.append( ", isRoot=" ).append( isRoot ); sb.append( ", inheritanceType=" ).append( inheritanceType ); @@ -179,6 +162,30 @@ public class ConfiguredClass { return sb.toString(); } + private ConfiguredClassType determineType() { + AnnotationInstance entityAnnotation = JandexHelper.getSingleAnnotation( + classInfo, JPADotNames.ENTITY + ); + if ( entityAnnotation != null ) { + return ConfiguredClassType.ENTITY; + } + + AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation( + classInfo, JPADotNames.MAPPED_SUPERCLASS + ); + if ( mappedSuperClassAnnotation != null ) { + return ConfiguredClassType.MAPPED_SUPERCLASS; + } + + AnnotationInstance embeddableAnnotation = JandexHelper.getSingleAnnotation( + classInfo, JPADotNames.EMBEDDABLE + ); + if ( embeddableAnnotation != null ) { + return ConfiguredClassType.EMBEDDABLE; + } + return ConfiguredClassType.NON_ENTITY; + } + private AccessType determineClassAccessType() { // default to the hierarchy access type to start with AccessType accessType = hierarchyAccessType; @@ -398,7 +405,8 @@ public class ConfiguredClass { private boolean definesItsOwnTable() { // mapped super classes and embeddables don't have their own tables - if ( isMappedSuperClass() || isEmbeddable() ) { + if ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( getType() ) || ConfiguredClassType.EMBEDDABLE + .equals( getType() ) ) { return false; } @@ -428,7 +436,9 @@ public class ConfiguredClass { } } } - else if ( parent != null && !parent.isMappedSuperClass && !parent.isEmbeddable ) { + else if ( parent != null + && !parent.getType().equals( ConfiguredClassType.MAPPED_SUPERCLASS ) + && !parent.getType().equals( ConfiguredClassType.EMBEDDABLE ) ) { tableName = parent.getPrimaryTableName(); } return tableName; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClassType.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClassType.java new file mode 100644 index 0000000000..553646830b --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClassType.java @@ -0,0 +1,34 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * Copyright (c) 2011, Red Hat Inc. or third-party contributors as + * indicated by the @author tags or express copyright attribution + * statements applied by the authors. All third-party contributions are + * distributed under license by Red Hat Inc. + * + * This copyrighted material is made available to anyone wishing to use, modify, + * copy, or redistribute it subject to the terms and conditions of the GNU + * Lesser General Public License, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this distribution; if not, write to: + * Free Software Foundation, Inc. + * 51 Franklin Street, Fifth Floor + * Boston, MA 02110-1301 USA + */ +package org.hibernate.metamodel.source.annotations; + +/** + * @author Hardy Ferentschik + */ +public enum ConfiguredClassType { + ENTITY, + MAPPED_SUPERCLASS, + EMBEDDABLE, + NON_ENTITY +} diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/HibernateDotNames.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/HibernateDotNames.java index 2a4f35ecdb..141735f90d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/HibernateDotNames.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/HibernateDotNames.java @@ -188,8 +188,6 @@ public interface HibernateDotNames { public static final DotName TYPE_DEFS = DotName.createSimple( TypeDefs.class.getName() ); public static final DotName WHERE = DotName.createSimple( Where.class.getName() ); public static final DotName WHERE_JOIN_TABLE = DotName.createSimple( WhereJoinTable.class.getName() ); - - }