From 1ae1d4b699e27a706deceee8878b01e268a45cdf Mon Sep 17 00:00:00 2001 From: Hardy Ferentschik Date: Fri, 29 Apr 2011 20:47:28 +0200 Subject: [PATCH] HHH-6174 extracting table name from hierarchy --- .../source/annotations/ConfiguredClass.java | 107 +++++++-- .../annotations/ConfiguredClassHierarchy.java | 4 +- .../source/annotations/EntityBinder.java | 11 + .../source/annotations/HibernateDotNames.java | 3 + .../source/annotations/JPADotNames.java | 3 + .../source/annotations/package-info.java | 28 +++ .../util/ConfiguredClassHierarchyBuilder.java | 49 +++- .../source/annotations/TableNameTest.java | 215 ++++++++++++++++++ .../ConfiguredClassHierarchyBuilderTest.java | 12 + 9 files changed, 406 insertions(+), 26 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/package-info.java create mode 100644 hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/TableNameTest.java 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 223c3ef93b..d4a4179e23 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 @@ -35,17 +35,18 @@ import java.util.List; import java.util.Map; import java.util.Set; import javax.persistence.AccessType; +import javax.persistence.InheritanceType; import com.fasterxml.classmate.ResolvedTypeWithMembers; import com.fasterxml.classmate.members.HierarchicType; import com.fasterxml.classmate.members.ResolvedMember; import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationTarget; +import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.ClassInfo; import org.jboss.jandex.FieldInfo; import org.jboss.jandex.MethodInfo; -import org.hibernate.AnnotationException; import org.hibernate.AssertionFailure; import org.hibernate.HibernateException; import org.hibernate.metamodel.source.annotations.util.JandexHelper; @@ -59,27 +60,61 @@ import org.hibernate.service.classloading.spi.ClassLoaderService; * @author Hardy Ferentschik */ public class ConfiguredClass { + /** + * The parent of this configured class or {@code null} in case this configured class is the root of a hierarchy. + */ private final ConfiguredClass parent; private final ClassInfo classInfo; private final Class clazz; + private final boolean isRoot; private final AccessType classAccessType; private final AccessType hierarchyAccessType; + + 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 Map mappedProperties; - public ConfiguredClass(ClassInfo info, ConfiguredClass parent, AccessType hierarchyAccessType, ServiceRegistry serviceRegistry, ResolvedTypeWithMembers resolvedType) { + public ConfiguredClass(ClassInfo info, + ConfiguredClass parent, + AccessType hierarchyAccessType, + InheritanceType inheritanceType, + ServiceRegistry serviceRegistry, + ResolvedTypeWithMembers resolvedType) { this.classInfo = info; this.parent = parent; this.isRoot = parent == null; this.hierarchyAccessType = hierarchyAccessType; - - AnnotationInstance mappedSuperClassAnnotation = assertNotEntityAndMappedSuperClass(); - + this.inheritanceType = inheritanceType; this.clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( info.toString() ); + + AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation( + classInfo, JPADotNames.MAPPED_SUPER_CLASS + ); isMappedSuperClass = mappedSuperClassAnnotation != null; + + AnnotationInstance embeddableAnnotation = JandexHelper.getSingleAnnotation( + classInfo, JPADotNames.MAPPED_SUPER_CLASS + ); + isEmbeddable = embeddableAnnotation != null; + + tableAnnotation = JandexHelper.getSingleAnnotation( + classInfo, JPADotNames.TABLE + ); + + // todo think about how exactly to handle embeddables regarding access type etc + classAccessType = determineClassAccessType(); + hasOwnTable = definesItsOwnTable(); + primaryTableName = determinePrimaryTableName(); + List properties = collectMappedProperties( resolvedType ); // make sure the properties are ordered by property name Collections.sort( properties ); @@ -110,6 +145,22 @@ public class ConfiguredClass { return isMappedSuperClass; } + public boolean isEmbeddable() { + return isEmbeddable; + } + + public InheritanceType getInheritanceType() { + return inheritanceType; + } + + public boolean hasOwnTable() { + return hasOwnTable; + } + + public String getPrimaryTableName() { + return primaryTableName; + } + public Iterable getMappedProperties() { return mappedProperties.values(); } @@ -126,6 +177,7 @@ public class ConfiguredClass { sb.append( ", mappedProperties=" ).append( mappedProperties ); sb.append( ", classAccessType=" ).append( classAccessType ); sb.append( ", isRoot=" ).append( isRoot ); + sb.append( ", inheritanceType=" ).append( inheritanceType ); sb.append( '}' ); return sb.toString(); } @@ -344,20 +396,39 @@ public class ConfiguredClass { } } - private AnnotationInstance assertNotEntityAndMappedSuperClass() { - //@Entity and @MappedSuperclass on the same class leads to a NPE down the road - AnnotationInstance jpaEntityAnnotation = JandexHelper.getSingleAnnotation( classInfo, JPADotNames.ENTITY ); - AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation( - classInfo, JPADotNames.MAPPED_SUPER_CLASS - ); - - if ( jpaEntityAnnotation != null && mappedSuperClassAnnotation != null ) { - throw new AnnotationException( - "An entity cannot be annotated with both @Entity and @MappedSuperclass: " - + classInfo.name().toString() - ); + private boolean definesItsOwnTable() { + // mapped super classes and embeddables don't have their own tables + if ( isMappedSuperClass() || isEmbeddable() ) { + return false; } - return mappedSuperClassAnnotation; + + if ( InheritanceType.SINGLE_TABLE.equals( inheritanceType ) ) { + if ( isRoot() ) { + return true; + } + else { + return false; + } + } + return true; + } + + private String determinePrimaryTableName() { + String tableName = null; + if ( hasOwnTable() ) { + tableName = clazz.getSimpleName(); + if ( tableAnnotation != null ) { + AnnotationValue value = tableAnnotation.value( "name" ); + String tmp = value == null ? null : value.asString(); + if ( tmp != null && !tmp.isEmpty() ) { + tableName = tmp; + } + } + } + else if ( parent != null && !parent.isMappedSuperClass && !parent.isEmbeddable ) { + tableName = parent.getPrimaryTableName(); + } + return tableName; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClassHierarchy.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClassHierarchy.java index fba6f7f79c..0e5b31cf7e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClassHierarchy.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClassHierarchy.java @@ -66,7 +66,9 @@ public class ConfiguredClassHierarchy implements Iterable { configuredClasses = new ArrayList(); ConfiguredClass parent = null; for ( ClassInfo info : classes ) { - ConfiguredClass configuredClass = new ConfiguredClass( info, parent, defaultAccessType, serviceRegistry, resolvedMembers ); + ConfiguredClass configuredClass = new ConfiguredClass( + info, parent, defaultAccessType, inheritanceType, serviceRegistry, resolvedMembers + ); configuredClasses.add( configuredClass ); parent = configuredClass; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java index 1bd2205699..325c969c7f 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java @@ -70,6 +70,17 @@ public class EntityBinder { } private void bindTable(EntityBinding entityBinding) { + +// this.schemaName = new Schema.Name( +// ( entityClazz.getSchema() == null ? +// hibernateMappingBinder.getDefaultSchemaName() : +// entityClazz.getSchema() ), +// ( entityClazz.getCatalog() == null ? +// hibernateMappingBinder.getDefaultCatalogName() : +// entityClazz.getCatalog() ) +// ); + + final Schema schema = meta.getDatabase().getSchema( null ); } 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 14674ac67d..349c5a2bdd 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 @@ -29,6 +29,7 @@ import org.hibernate.annotations.Check; import org.hibernate.annotations.Entity; import org.hibernate.annotations.FetchProfile; import org.hibernate.annotations.FetchProfiles; +import org.hibernate.annotations.Table; /** * Defines the dot names for the Hibernate specific annotations. @@ -37,6 +38,8 @@ import org.hibernate.annotations.FetchProfiles; */ public interface HibernateDotNames { public static final DotName ENTITY = DotName.createSimple( Entity.class.getName() ); + public static final DotName TABLE = DotName.createSimple( Table.class.getName() ); + public static final DotName FETCH_PROFILES = DotName.createSimple( FetchProfiles.class.getName() ); public static final DotName FETCH_PROFILE = DotName.createSimple( FetchProfile.class.getName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JPADotNames.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JPADotNames.java index 0e1b32e3d1..cf2b2d37b4 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JPADotNames.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JPADotNames.java @@ -24,6 +24,7 @@ package org.hibernate.metamodel.source.annotations; import javax.persistence.Access; +import javax.persistence.Embeddable; import javax.persistence.EmbeddedId; import javax.persistence.Entity; import javax.persistence.Id; @@ -42,6 +43,8 @@ import org.jboss.jandex.DotName; public interface JPADotNames { public static final DotName ENTITY = DotName.createSimple( Entity.class.getName() ); public static final DotName MAPPED_SUPER_CLASS = DotName.createSimple( MappedSuperclass.class.getName() ); + public static final DotName EMBEDDABLE = DotName.createSimple( Embeddable.class.getName() ); + public static final DotName INHERITANCE = DotName.createSimple( Inheritance.class.getName() ); public static final DotName ID = DotName.createSimple( Id.class.getName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/package-info.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/package-info.java new file mode 100644 index 0000000000..15b17fa268 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/package-info.java @@ -0,0 +1,28 @@ +/* + * 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; + +/** + * This package contains the core binding code for binding annotation based configuration to the Hibernate metadata model. + */ \ No newline at end of file diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/util/ConfiguredClassHierarchyBuilder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/util/ConfiguredClassHierarchyBuilder.java index 2ff26b79c3..d2b3e9e169 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/util/ConfiguredClassHierarchyBuilder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/util/ConfiguredClassHierarchyBuilder.java @@ -35,6 +35,7 @@ import org.jboss.jandex.ClassInfo; import org.jboss.jandex.DotName; import org.jboss.jandex.Index; +import org.hibernate.AnnotationException; import org.hibernate.metamodel.source.annotations.ConfiguredClassHierarchy; import org.hibernate.metamodel.source.annotations.JPADotNames; import org.hibernate.service.ServiceRegistry; @@ -54,19 +55,14 @@ public class ConfiguredClassHierarchyBuilder { * @param index The annotation index * @param serviceRegistry The service registry * - * @return a set of {@code ConfiguredClassHierarchy}s. One for each configured "leaf" entity. + * @return a set of {@code ConfiguredClassHierarchy}s. One for each "leaf" entity. */ public static Set createEntityHierarchies(Index index, ServiceRegistry serviceRegistry) { ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class ); Map> processedClassInfos = new HashMap>(); for ( ClassInfo info : index.getKnownClasses() ) { - AnnotationInstance jpaEntityAnnotation = JandexHelper.getSingleAnnotation( info, JPADotNames.ENTITY ); - AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation( - info, JPADotNames.MAPPED_SUPER_CLASS - ); - // we are only interested in building the class hierarchies for @Entity or @MappedSuperclass w - if ( jpaEntityAnnotation == null && mappedSuperClassAnnotation == null ) { + if ( !isConfiguredClass( info ) ) { continue; } @@ -110,6 +106,29 @@ public class ConfiguredClassHierarchyBuilder { return hierarchies; } + private static boolean isConfiguredClass(ClassInfo info) { + boolean isConfiguredClass = true; + AnnotationInstance jpaEntityAnnotation = JandexHelper.getSingleAnnotation( info, JPADotNames.ENTITY ); + AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation( + info, JPADotNames.MAPPED_SUPER_CLASS + ); + AnnotationInstance embeddableAnnotation = JandexHelper.getSingleAnnotation( + info, JPADotNames.EMBEDDABLE + ); + + // we are only interested in building the class hierarchies for @Entity or @MappedSuperclass w + if ( jpaEntityAnnotation == null && mappedSuperClassAnnotation == null && embeddableAnnotation == null ) { + return false; + } + + // some sanity checks + String className = info.toString(); + assertNotEntityAndMappedSuperClass( jpaEntityAnnotation, mappedSuperClassAnnotation, className ); + assertNotEntityAndEmbeddable( jpaEntityAnnotation, embeddableAnnotation, className ); + + return isConfiguredClass; + } + private static boolean existsHierarchyWithClassInfoAsLeaf(Map> processedClassInfos, ClassInfo tmpClassInfo) { if ( !processedClassInfos.containsKey( tmpClassInfo ) ) { return false; @@ -118,6 +137,22 @@ public class ConfiguredClassHierarchyBuilder { List classInfoList = processedClassInfos.get( tmpClassInfo ); return classInfoList.get( classInfoList.size() - 1 ).equals( tmpClassInfo ); } + + private static void assertNotEntityAndMappedSuperClass(AnnotationInstance jpaEntityAnnotation, AnnotationInstance mappedSuperClassAnnotation, String className) { + if ( jpaEntityAnnotation != null && mappedSuperClassAnnotation != null ) { + throw new AnnotationException( + "An entity cannot be annotated with both @Entity and @MappedSuperclass. " + className + " has both annotations." + ); + } + } + + private static void assertNotEntityAndEmbeddable(AnnotationInstance jpaEntityAnnotation, AnnotationInstance embeddableAnnotation, String className) { + if ( jpaEntityAnnotation != null && embeddableAnnotation != null ) { + throw new AnnotationException( + "An entity cannot be annotated with both @Entity and @Embeddable. " + className + " has both annotations." + ); + } + } } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/TableNameTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/TableNameTest.java new file mode 100644 index 0000000000..d3adf78fba --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/TableNameTest.java @@ -0,0 +1,215 @@ +/* + * 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; + +import java.util.Iterator; +import java.util.Set; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.Inheritance; +import javax.persistence.InheritanceType; +import javax.persistence.Table; + +import org.jboss.jandex.ClassInfo; +import org.jboss.jandex.DotName; +import org.jboss.jandex.Index; +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder; +import org.hibernate.metamodel.source.annotations.util.JandexHelper; +import org.hibernate.service.ServiceRegistryBuilder; +import org.hibernate.service.classloading.spi.ClassLoaderService; +import org.hibernate.service.internal.BasicServiceRegistryImpl; +import org.hibernate.testing.junit4.BaseUnitTestCase; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static org.junit.Assert.assertFalse; + +/** + * @author Hardy Ferentschik + */ +public class TableNameTest extends BaseUnitTestCase { + + private BasicServiceRegistryImpl serviceRegistry; + private ClassLoaderService service; + + @Before + public void setUp() { + serviceRegistry = (BasicServiceRegistryImpl) new ServiceRegistryBuilder().buildServiceRegistry(); + service = serviceRegistry.getService( ClassLoaderService.class ); + } + + @After + public void tearDown() { + serviceRegistry.destroy(); + } + + @Test + public void testSingleInheritanceDefaultTableName() { + @Entity + class A { + @Id + @GeneratedValue + private int id; + } + + @Entity + class B extends A { + } + + Index index = JandexHelper.indexForClass( service, A.class, B.class ); + Set hierarchies = ConfiguredClassHierarchyBuilder.createEntityHierarchies( + index, serviceRegistry + ); + assertEquals( "There should be only one hierarchy", 1, hierarchies.size() ); + + Iterator iter = hierarchies.iterator().next().iterator(); + ConfiguredClass configuredClass = iter.next(); + ClassInfo info = configuredClass.getClassInfo(); + assertEquals( "wrong class", DotName.createSimple( A.class.getName() ), info.name() ); + assertTrue( configuredClass.hasOwnTable() ); + Assert.assertEquals( + "wrong inheritance type", InheritanceType.SINGLE_TABLE, configuredClass.getInheritanceType() + ); + Assert.assertEquals( + "wrong table name", "A", configuredClass.getPrimaryTableName() + ); + + assertTrue( iter.hasNext() ); + configuredClass = iter.next(); + info = configuredClass.getClassInfo(); + assertEquals( "wrong class", DotName.createSimple( B.class.getName() ), info.name() ); + assertFalse( configuredClass.hasOwnTable() ); + Assert.assertEquals( + "wrong inheritance type", InheritanceType.SINGLE_TABLE, configuredClass.getInheritanceType() + ); + Assert.assertEquals( + "wrong table name", "A", configuredClass.getPrimaryTableName() + ); + + assertFalse( iter.hasNext() ); + } + + @Test + public void testTablePerClassDefaultTableName() { + @Entity + @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS) + class A { + @Id + @GeneratedValue + private int id; + } + + @Entity + class B extends A { + } + + Index index = JandexHelper.indexForClass( service, A.class, B.class ); + Set hierarchies = ConfiguredClassHierarchyBuilder.createEntityHierarchies( + index, serviceRegistry + ); + assertEquals( "There should be only one hierarchy", 1, hierarchies.size() ); + + Iterator iter = hierarchies.iterator().next().iterator(); + ConfiguredClass configuredClass = iter.next(); + ClassInfo info = configuredClass.getClassInfo(); + assertEquals( "wrong class", DotName.createSimple( A.class.getName() ), info.name() ); + assertTrue( configuredClass.hasOwnTable() ); + Assert.assertEquals( + "wrong inheritance type", InheritanceType.TABLE_PER_CLASS, configuredClass.getInheritanceType() + ); + Assert.assertEquals( + "wrong table name", "A", configuredClass.getPrimaryTableName() + ); + + assertTrue( iter.hasNext() ); + configuredClass = iter.next(); + info = configuredClass.getClassInfo(); + assertEquals( "wrong class", DotName.createSimple( B.class.getName() ), info.name() ); + assertTrue( configuredClass.hasOwnTable() ); + Assert.assertEquals( + "wrong inheritance type", InheritanceType.TABLE_PER_CLASS, configuredClass.getInheritanceType() + ); + Assert.assertEquals( + "wrong table name", "B", configuredClass.getPrimaryTableName() + ); + + assertFalse( iter.hasNext() ); + } + + @Test + public void testJoinedSubclassDefaultTableName() { + @Entity + @Inheritance(strategy = InheritanceType.JOINED) + @Table(name = "FOO") + class A { + @Id + @GeneratedValue + private int id; + } + + @Entity + class B extends A { + } + + Index index = JandexHelper.indexForClass( service, B.class, A.class ); + Set hierarchies = ConfiguredClassHierarchyBuilder.createEntityHierarchies( + index, serviceRegistry + ); + assertEquals( "There should be only one hierarchy", 1, hierarchies.size() ); + + Iterator iter = hierarchies.iterator().next().iterator(); + ConfiguredClass configuredClass = iter.next(); + ClassInfo info = configuredClass.getClassInfo(); + assertEquals( "wrong class", DotName.createSimple( A.class.getName() ), info.name() ); + assertTrue( configuredClass.hasOwnTable() ); + Assert.assertEquals( + "wrong inheritance type", InheritanceType.JOINED, configuredClass.getInheritanceType() + ); + Assert.assertEquals( + "wrong table name", "FOO", configuredClass.getPrimaryTableName() + ); + + assertTrue( iter.hasNext() ); + configuredClass = iter.next(); + info = configuredClass.getClassInfo(); + assertEquals( "wrong class", DotName.createSimple( B.class.getName() ), info.name() ); + assertTrue( configuredClass.hasOwnTable() ); + Assert.assertEquals( + "wrong inheritance type", InheritanceType.JOINED, configuredClass.getInheritanceType() + ); + Assert.assertEquals( + "wrong table name", "B", configuredClass.getPrimaryTableName() + ); + + assertFalse( iter.hasNext() ); + } +} + + diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/ConfiguredClassHierarchyBuilderTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/ConfiguredClassHierarchyBuilderTest.java index 86d5a44f11..5f4a46bb9e 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/ConfiguredClassHierarchyBuilderTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/ConfiguredClassHierarchyBuilderTest.java @@ -26,6 +26,7 @@ package org.hibernate.metamodel.source.annotations.util; import java.util.Iterator; import java.util.Set; import javax.persistence.AccessType; +import javax.persistence.Embeddable; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @@ -157,6 +158,17 @@ public class ConfiguredClassHierarchyBuilderTest extends BaseUnitTestCase { ConfiguredClassHierarchyBuilder.createEntityHierarchies( index, serviceRegistry ); } + @Test(expected = AnnotationException.class) + public void testEntityAndEmbeddableAnnotations() { + @Entity + @Embeddable + class EntityAndEmbeddable { + } + + Index index = JandexHelper.indexForClass( service, EntityAndEmbeddable.class ); + ConfiguredClassHierarchyBuilder.createEntityHierarchies( index, serviceRegistry ); + } + @Test(expected = AnnotationException.class) public void testNoIdAnnotation() {