HHH-6201 Create attribute and attribute bindings for mapped super classes

This commit is contained in:
Hardy Ferentschik 2011-07-05 15:26:13 +02:00
parent 546ba3c550
commit ec482d3d0e
6 changed files with 333 additions and 136 deletions

View File

@ -36,8 +36,13 @@ import org.jboss.logging.Logger;
import org.hibernate.HibernateException;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.metamodel.MetadataSources;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.domain.Hierarchical;
import org.hibernate.metamodel.domain.NonEntity;
import org.hibernate.metamodel.domain.Superclass;
import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings;
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassType;
import org.hibernate.metamodel.source.annotations.entity.EntityBinder;
import org.hibernate.metamodel.source.annotations.entity.EntityClass;
import org.hibernate.metamodel.source.annotations.global.FetchProfileBinder;
@ -56,10 +61,11 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
/**
* Main class responsible to creating and binding the Hibernate meta-model from annotations.
* This binder only has to deal with annotation index. XML configuration is already processed and pseudo annotations
* are added to the annotation index.
* This binder only has to deal with the (jandex) annotation index/repository. XML configuration is already processed
* and pseudo annotations are created.
*
* @author Hardy Ferentschik
* @see org.hibernate.metamodel.source.annotations.xml.OrmXmlParser
*/
public class AnnotationBinder implements Binder {
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
@ -105,6 +111,12 @@ public class AnnotationBinder implements Binder {
}
}
/**
* Adds the class w/ the specified name to the jandex index.
*
* @param indexer The jandex indexer
* @param className the fully qualified class name to be indexed
*/
private void indexClass(Indexer indexer, String className) {
InputStream stream = classLoaderService().locateResourceStream( className );
try {
@ -134,16 +146,33 @@ public class AnnotationBinder implements Binder {
@Override
public void bindMappingMetadata(MetadataSources sources, List<String> processedEntityNames) {
// need to order our annotated entities into an order we can process
AnnotationBindingContext context = new AnnotationBindingContext( index, metadata.getServiceRegistry() );
Set<ConfiguredClassHierarchy<EntityClass>> hierarchies = ConfiguredClassHierarchyBuilder.createEntityHierarchies( context );
// need to order our annotated entities into an order we can process
Set<ConfiguredClassHierarchy<EntityClass>> hierarchies = ConfiguredClassHierarchyBuilder.createEntityHierarchies(
context
);
// now we process each hierarchy one at the time
Hierarchical parent = null;
for ( ConfiguredClassHierarchy<EntityClass> hierarchy : hierarchies ) {
for ( EntityClass entityClass : hierarchy ) {
LOG.bindingEntityFromAnnotatedClass( entityClass.getName() );
EntityBinder entityBinder = new EntityBinder( metadata, entityClass );
entityBinder.bind();
// for classes annotated w/ @Entity we create a EntityBinding
if ( ConfiguredClassType.ENTITY.equals( entityClass.getConfiguredClassType() ) ) {
LOG.bindingEntityFromAnnotatedClass( entityClass.getName() );
EntityBinder entityBinder = new EntityBinder( metadata, entityClass, parent );
EntityBinding binding = entityBinder.bind();
parent = binding.getEntity();
}
// for classes annotated w/ @MappedSuperclass we just create the domain instance
// the attribute bindings will be part of the first entity subclass
else if ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( entityClass.getConfiguredClassType() ) ) {
parent = new Superclass( entityClass.getName(), parent );
}
// for classes which are not annotated at all we create the NonEntity domain class
// todo - not sure whether this is needed. It might be that we don't need this information (HF)
else {
parent = new NonEntity( entityClass.getName(), parent );
}
}
}
}

View File

@ -24,6 +24,7 @@
package org.hibernate.metamodel.source.annotations.entity;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.persistence.GenerationType;
@ -65,7 +66,6 @@ import org.hibernate.metamodel.relational.UniqueKey;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.attribute.AssociationAttribute;
import org.hibernate.metamodel.source.annotations.attribute.DiscriminatorColumnValues;
import org.hibernate.metamodel.source.annotations.attribute.MappedAttribute;
import org.hibernate.metamodel.source.annotations.attribute.SimpleAttribute;
import org.hibernate.metamodel.source.annotations.attribute.state.binding.AttributeBindingStateImpl;
@ -88,22 +88,20 @@ import org.hibernate.persister.entity.EntityPersister;
public class EntityBinder {
private final EntityClass entityClass;
private final MetadataImplementor meta;
private final Hierarchical superType;
private Schema.Name schemaName;
public EntityBinder(MetadataImplementor metadata, EntityClass entityClass) {
public EntityBinder(MetadataImplementor metadata, EntityClass entityClass, Hierarchical superType) {
this.entityClass = entityClass;
this.meta = metadata;
this.superType = superType;
}
public void bind() {
public EntityBinding bind() {
EntityBinding entityBinding = new EntityBinding();
EntityBindingStateImpl entityBindingState = new EntityBindingStateImpl( getSuperType(), entityClass );
EntityBindingStateImpl entityBindingState = new EntityBindingStateImpl( superType, entityClass );
bindJpaEntityAnnotation( entityBindingState );
bindHibernateEntityAnnotation( entityBindingState ); // optional hibernate specific @org.hibernate.annotations.Entity
schemaName = createSchemaName();
bindTable( entityBinding );
// bind entity level annotations
@ -115,18 +113,16 @@ public class EntityBinder {
bindCustomSQL( entityBindingState );
bindRowId( entityBindingState );
bindBatchSize( entityBindingState );
entityBinding.initialize( meta, entityBindingState );
bindInheritance( entityBinding );
// bind all attributes - simple as well as associations
bindAttributes( entityBinding );
bindEmbeddedAttributes( entityBinding );
// take care of the id, attributes and relations
if ( entityClass.isRoot() ) {
// take care of the id, attributes and relations
if ( entityClass.isEntityRoot() ) {
bindId( entityBinding );
}
@ -134,6 +130,7 @@ public class EntityBinder {
// last, but not least we initialize and register the new EntityBinding
meta.addEntity( entityBinding );
return entityBinding;
}
private void bindTableUniqueConstraints(EntityBinding entityBinding) {
@ -199,12 +196,7 @@ public class EntityBinder {
entityClass.getClassInfo()
);
SimpleAttribute discriminatorAttribute = SimpleAttribute.createDiscriminatorAttribute( typeAnnotations );
bindSingleMappedAttribute( entityBinding, entityBinding.getEntity(), discriminatorAttribute );
if ( !( discriminatorAttribute.getColumnValues() instanceof DiscriminatorColumnValues ) ) {
throw new AssertionFailure( "Expected discriminator column values" );
}
}
private void bindWhereFilter(EntityBindingStateImpl entityBindingState) {
@ -426,7 +418,7 @@ public class EntityBinder {
}
private void bindTable(EntityBinding entityBinding) {
final Schema schema = meta.getDatabase().getSchema( schemaName );
final Schema schema = meta.getDatabase().getSchema( createSchemaName() );
final Identifier tableName = Identifier.toIdentifier( entityClass.getPrimaryTableName() );
org.hibernate.metamodel.relational.Table table = schema.getTable( tableName );
if ( table == null ) {
@ -476,40 +468,9 @@ public class EntityBinder {
entityBindingState.setJpaEntityName( name );
}
private void bindEmbeddedIdAnnotation(EntityBinding entityBinding) {
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation(
entityClass.getClassInfo(), JPADotNames.EMBEDDED_ID
);
String idName = JandexHelper.getPropertyName( idAnnotation.target() );
MappedAttribute idAttribute = entityClass.getMappedAttribute( idName );
if ( !( idAttribute instanceof SimpleAttribute ) ) {
throw new AssertionFailure( "Unexpected attribute type for id attribute" );
}
SingularAttribute attribute = entityBinding.getEntity().getOrCreateComponentAttribute( idName );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( attribute );
attributeBinding.initialize( new AttributeBindingStateImpl( (SimpleAttribute) idAttribute ) );
TupleRelationalStateImpl state = new TupleRelationalStateImpl();
EmbeddableClass embeddableClass = entityClass.getEmbeddedClasses().get( idName );
for ( MappedAttribute attr : embeddableClass.getMappedAttributes() ) {
state.addValueState( new ColumnRelationalStateImpl( (SimpleAttribute) attr, meta ) );
}
attributeBinding.initialize( state );
Map<String,String> parms = new HashMap<String, String>( 1 );
parms.put( IdentifierGenerator.ENTITY_NAME, entityBinding.getEntity().getName() );
IdGenerator generator = new IdGenerator( "NAME","assigned", parms);
entityBinding.getEntityIdentifier().setIdGenerator( generator );
// entityBinding.getEntityIdentifier().createIdentifierGenerator( meta.getIdentifierGeneratorFactory() );
}
private void bindSingleIdAnnotation(EntityBinding entityBinding) {
private void bindEmbeddedIdAnnotation(EntityBinding entityBinding) {
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation(
entityClass.getClassInfo(), JPADotNames.ID
entityClass.getClassInfo(), JPADotNames.EMBEDDED_ID
);
String idName = JandexHelper.getPropertyName( idAnnotation.target() );
@ -518,13 +479,59 @@ public class EntityBinder {
throw new AssertionFailure( "Unexpected attribute type for id attribute" );
}
Attribute attribute = entityBinding.getEntity().getOrCreateSingularAttribute( idName );
SingularAttribute attribute = entityBinding.getEntity().getOrCreateComponentAttribute( idName );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( attribute );
attributeBinding.initialize( new AttributeBindingStateImpl( (SimpleAttribute) idAttribute ) );
TupleRelationalStateImpl state = new TupleRelationalStateImpl();
EmbeddableClass embeddableClass = entityClass.getEmbeddedClasses().get( idName );
for ( SimpleAttribute attr : embeddableClass.getSimpleAttributes() ) {
state.addValueState( new ColumnRelationalStateImpl( attr, meta ) );
}
attributeBinding.initialize( state );
Map<String, String> parms = new HashMap<String, String>( 1 );
parms.put( IdentifierGenerator.ENTITY_NAME, entityBinding.getEntity().getName() );
IdGenerator generator = new IdGenerator( "NAME", "assigned", parms );
entityBinding.getEntityIdentifier().setIdGenerator( generator );
// entityBinding.getEntityIdentifier().createIdentifierGenerator( meta.getIdentifierGeneratorFactory() );
}
private void bindSingleIdAnnotation(EntityBinding entityBinding) {
// we know we are dealing w/ a single @Id, but potentially it is defined in a mapped super class
ConfiguredClass configuredClass = entityClass;
EntityClass superEntity = entityClass.getEntityParent();
Hierarchical container = entityBinding.getEntity();
Iterator<SimpleAttribute> iter = null;
while ( configuredClass != null && configuredClass != superEntity ) {
iter = configuredClass.getIdAttributes().iterator();
if ( iter.hasNext() ) {
break;
}
configuredClass = configuredClass.getParent();
container = container.getSuperType();
}
// if we could not find the attribute our assumptions were wrong
if ( iter == null || !iter.hasNext() ) {
throw new AnnotationException(
String.format(
"Unable to find id attribute for class %s",
entityClass.getName()
)
);
}
// now that we have the id attribute we can create the attribute and binding
MappedAttribute idAttribute = iter.next();
Attribute attribute = container.getOrCreateSingularAttribute( idAttribute.getName() );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( attribute );
attributeBinding.initialize( new AttributeBindingStateImpl( (SimpleAttribute) idAttribute ) );
attributeBinding.initialize( new ColumnRelationalStateImpl( (SimpleAttribute) idAttribute, meta ) );
bindSingleIdGeneratedValue( entityBinding, idName );
bindSingleIdGeneratedValue( entityBinding, idAttribute.getName() );
}
private void bindSingleIdGeneratedValue(EntityBinding entityBinding, String idPropertyName) {
@ -552,7 +559,7 @@ public class EntityBinder {
if ( idGenerator == null ) {
throw new MappingException(
String.format(
"@GeneratedValue on %s.%s refering an undefined generator [%s]",
"@GeneratedValue on %s.%s referring an undefined generator [%s]",
entityClass.getName(),
idName,
generator
@ -580,7 +587,7 @@ public class EntityBinder {
)
);
}
if( idGenerator == null ) {
if ( idGenerator == null ) {
idGenerator = new IdGenerator( "NAME", strategy, new HashMap<String, String>() );
entityBinding.getEntityIdentifier().setIdGenerator( idGenerator );
}
@ -588,44 +595,74 @@ public class EntityBinder {
}
private void bindAttributes(EntityBinding entityBinding) {
for ( MappedAttribute mappedAttribute : entityClass.getMappedAttributes() ) {
if ( mappedAttribute instanceof AssociationAttribute ) {
bindAssociationAttribute(
entityBinding,
entityBinding.getEntity(),
(AssociationAttribute) mappedAttribute
);
}
else {
bindSingleMappedAttribute(
entityBinding,
entityBinding.getEntity(),
(SimpleAttribute) mappedAttribute
);
}
// bind the attributes of this entity
AttributeContainer entity = entityBinding.getEntity();
bindAttributes( entityBinding, entity, entityClass );
// bind potential mapped super class attributes
ConfiguredClass parent = entityClass.getParent();
Hierarchical superTypeContainer = entityBinding.getEntity().getSuperType();
while ( containsPotentialMappedSuperclassAttributes( parent ) ) {
bindAttributes( entityBinding, superTypeContainer, parent );
parent = parent.getParent();
superTypeContainer = superTypeContainer.getSuperType();
}
}
private boolean containsPotentialMappedSuperclassAttributes(ConfiguredClass parent) {
return parent != null && ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( parent.getConfiguredClassType() ) ||
ConfiguredClassType.NON_ENTITY.equals( parent.getConfiguredClassType() ) );
}
private void bindAttributes(EntityBinding entityBinding, AttributeContainer attributeContainer, ConfiguredClass configuredClass) {
for ( SimpleAttribute simpleAttribute : configuredClass.getSimpleAttributes() ) {
bindSingleMappedAttribute(
entityBinding,
attributeContainer,
simpleAttribute
);
}
for ( AssociationAttribute associationAttribute : configuredClass.getAssociationAttributes() ) {
bindAssociationAttribute(
entityBinding,
attributeContainer,
associationAttribute
);
}
}
private void bindEmbeddedAttributes(EntityBinding entityBinding) {
for ( Map.Entry<String, EmbeddableClass> entry : entityClass.getEmbeddedClasses().entrySet() ) {
AttributeContainer entity = entityBinding.getEntity();
bindEmbeddedAttributes( entityBinding, entity, entityClass );
// bind potential mapped super class embeddables
ConfiguredClass parent = entityClass.getParent();
Hierarchical superTypeContainer = entityBinding.getEntity().getSuperType();
while ( containsPotentialMappedSuperclassAttributes( parent ) ) {
bindEmbeddedAttributes( entityBinding, superTypeContainer, parent );
parent = parent.getParent();
superTypeContainer = superTypeContainer.getSuperType();
}
}
private void bindEmbeddedAttributes(EntityBinding entityBinding, AttributeContainer attributeContainer, ConfiguredClass configuredClass) {
for ( Map.Entry<String, EmbeddableClass> entry : configuredClass.getEmbeddedClasses().entrySet() ) {
String attributeName = entry.getKey();
EmbeddableClass embeddedClass = entry.getValue();
SingularAttribute component = entityBinding.getEntity().getOrCreateComponentAttribute( attributeName );
for ( MappedAttribute mappedAttribute : embeddedClass.getMappedAttributes() ) {
if ( mappedAttribute instanceof AssociationAttribute ) {
bindAssociationAttribute(
entityBinding,
component.getAttributeContainer(),
(AssociationAttribute) mappedAttribute
);
}
else {
bindSingleMappedAttribute(
entityBinding,
component.getAttributeContainer(),
(SimpleAttribute) mappedAttribute
);
}
SingularAttribute component = attributeContainer.getOrCreateComponentAttribute( attributeName );
for ( SimpleAttribute simpleAttribute : embeddedClass.getSimpleAttributes() ) {
bindSingleMappedAttribute(
entityBinding,
component.getAttributeContainer(),
simpleAttribute
);
}
for ( AssociationAttribute associationAttribute : embeddedClass.getAssociationAttributes() ) {
bindAssociationAttribute(
entityBinding,
component.getAttributeContainer(),
associationAttribute
);
}
}
}
@ -754,21 +791,5 @@ public class EntityBinder {
entityBindingState.setExplicitPolymorphism( PolymorphismType.EXPLICIT.equals( polymorphism ) );
entityBindingState.setOptimisticLock( optimisticLock );
}
private Hierarchical getSuperType() {
ConfiguredClass parent = entityClass.getParent();
if ( parent == null ) {
return null;
}
EntityBinding parentBinding = meta.getEntityBinding( parent.getName() );
if ( parentBinding == null ) {
throw new AssertionFailure(
"Parent entity " + parent.getName() + " of entity " + entityClass.getName() + " not yet created!"
);
}
return parentBinding.getEntity();
}
}

View File

@ -23,12 +23,14 @@
*/
package org.hibernate.metamodel.source.annotations.entity;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.AccessType;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.hibernate.AnnotationException;
import org.hibernate.MappingException;
@ -38,18 +40,17 @@ import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
/**
* Represents an entity, mapped superclass or component configured via annotations/xml.
* Represents an entity or mapped superclass configured via annotations/xml.
*
* @author Hardy Ferentschik
*/
public class EntityClass extends ConfiguredClass {
private final AccessType hierarchyAccessType;
private final InheritanceType inheritanceType;
private final boolean hasOwnTable;
private final String primaryTableName;
private final IdType idType;
private final EntityClass jpaEntityParent;
public EntityClass(ClassInfo classInfo,
EntityClass parent,
@ -61,11 +62,27 @@ public class EntityClass extends ConfiguredClass {
this.hierarchyAccessType = hierarchyAccessType;
this.inheritanceType = inheritanceType;
this.idType = determineIdType();
this.jpaEntityParent = findJpaEntitySuperClass();
this.hasOwnTable = definesItsOwnTable();
this.primaryTableName = determinePrimaryTableName();
}
/**
* @return Returns the next JPA super entity for this entity class or {@code null} in case there is none.
*/
public EntityClass getEntityParent() {
return jpaEntityParent;
}
/**
* @return Returns {@code true} is this entity class is the root of the class hierarchy in the JPA sense, which
* means there are no more super classes which are annotated with @Entity. There can, however, be mapped superclasses
* or non entities in the actual java type hierarchy.
*/
public boolean isEntityRoot() {
return jpaEntityParent == null;
}
public InheritanceType getInheritanceType() {
return inheritanceType;
}
@ -86,7 +103,7 @@ public class EntityClass extends ConfiguredClass {
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "EntityClass" );
sb.append( "{name=" ).append( getName() );
sb.append( "{name=" ).append( getConfiguredClass().getSimpleName() );
sb.append( ", hierarchyAccessType=" ).append( hierarchyAccessType );
sb.append( ", inheritanceType=" ).append( inheritanceType );
sb.append( ", hasOwnTable=" ).append( hasOwnTable );
@ -97,18 +114,33 @@ public class EntityClass extends ConfiguredClass {
}
private boolean definesItsOwnTable() {
// mapped super classes and embeddables don't have their own tables
if ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( getConfiguredClassType() ) || ConfiguredClassType.EMBEDDABLE
.equals( getConfiguredClassType() ) ) {
// mapped super classes don't have their own tables
if ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( getConfiguredClassType() ) ) {
return false;
}
if ( InheritanceType.SINGLE_TABLE.equals( inheritanceType ) ) {
return isRoot();
if ( isEntityRoot() ) {
return true;
}
else {
return false;
}
}
return true;
}
private EntityClass findJpaEntitySuperClass() {
ConfiguredClass tmpConfiguredClass = this.getParent();
while ( tmpConfiguredClass != null ) {
if ( ConfiguredClassType.ENTITY.equals( tmpConfiguredClass.getConfiguredClassType() ) ) {
return (EntityClass) tmpConfiguredClass;
}
tmpConfiguredClass = tmpConfiguredClass.getParent();
}
return null;
}
private String determinePrimaryTableName() {
String tableName = null;
if ( hasOwnTable() ) {
@ -125,26 +157,23 @@ public class EntityClass extends ConfiguredClass {
}
}
else if ( getParent() != null
&& !getParent().getConfiguredClassType().equals( ConfiguredClassType.MAPPED_SUPERCLASS )
&& !getParent().getConfiguredClassType().equals( ConfiguredClassType.EMBEDDABLE ) ) {
&& !getParent().getConfiguredClassType().equals( ConfiguredClassType.MAPPED_SUPERCLASS ) ) {
tableName = ( (EntityClass) getParent() ).getPrimaryTableName();
}
return tableName;
}
private IdType determineIdType() {
List<AnnotationInstance> idAnnotations = getClassInfo().annotations().get( JPADotNames.ID );
List<AnnotationInstance> embeddedIdAnnotations = getClassInfo()
.annotations()
.get( JPADotNames.EMBEDDED_ID );
List<AnnotationInstance> idAnnotations = findIdAnnotations( JPADotNames.ID );
List<AnnotationInstance> embeddedIdAnnotations = findIdAnnotations( JPADotNames.EMBEDDED_ID );
if ( idAnnotations != null && embeddedIdAnnotations != null ) {
if ( !idAnnotations.isEmpty() && !embeddedIdAnnotations.isEmpty() ) {
throw new MappingException(
"@EmbeddedId and @Id cannot be used together. Check the configuration for " + getName() + "."
);
}
if ( embeddedIdAnnotations != null ) {
if ( !embeddedIdAnnotations.isEmpty() ) {
if ( embeddedIdAnnotations.size() == 1 ) {
return IdType.EMBEDDED;
}
@ -153,7 +182,7 @@ public class EntityClass extends ConfiguredClass {
}
}
if ( idAnnotations != null ) {
if ( !idAnnotations.isEmpty() ) {
if ( idAnnotations.size() == 1 ) {
return IdType.SIMPLE;
}
@ -163,4 +192,21 @@ public class EntityClass extends ConfiguredClass {
}
return IdType.NONE;
}
private List<AnnotationInstance> findIdAnnotations(DotName idAnnotationType) {
List<AnnotationInstance> idAnnotationList = new ArrayList<AnnotationInstance>();
if ( getClassInfo().annotations().get( idAnnotationType ) != null ) {
idAnnotationList.addAll( getClassInfo().annotations().get( idAnnotationType ) );
}
ConfiguredClass parent = getParent();
while ( parent != null && ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( parent.getConfiguredClassType() ) ||
ConfiguredClassType.NON_ENTITY.equals( parent.getConfiguredClassType() ) ) ) {
if ( parent.getClassInfo().annotations().get( idAnnotationType ) != null ) {
idAnnotationList.addAll( parent.getClassInfo().annotations().get( idAnnotationType ) );
}
parent = parent.getParent();
}
return idAnnotationList;
}
}

View File

@ -78,11 +78,11 @@ public class EntityBindingStateImpl implements EntityBindingState {
private Set<String> synchronizedTableNames;
public EntityBindingStateImpl(Hierarchical superType, EntityClass configuredClass) {
this.className = configuredClass.getName();
public EntityBindingStateImpl(Hierarchical superType, EntityClass entityClass) {
this.className = entityClass.getName();
this.superType = superType;
this.isRoot = configuredClass.isRoot();
this.inheritanceType = configuredClass.getInheritanceType();
this.isRoot = entityClass.isEntityRoot();
this.inheritanceType = entityClass.getInheritanceType();
this.synchronizedTableNames = new HashSet<String>();
this.batchSize = -1;
}

View File

@ -0,0 +1,101 @@
/*
* 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.source.annotations.entity;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import org.junit.Test;
import org.hibernate.action.internal.EntityIdentityInsertAction;
import org.hibernate.metamodel.binding.AttributeBinding;
import org.hibernate.metamodel.binding.EntityBinding;
import org.hibernate.metamodel.binding.EntityIdentifier;
import org.hibernate.metamodel.domain.NonEntity;
import org.hibernate.metamodel.domain.Superclass;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
/**
* Tests for {@code j.p.AttributeOverrides} and {@code j.p.AttributeOverride}.
*
* @author Hardy Ferentschik
*/
public class MappedSuperclassWithAttributeOverrideTests extends BaseAnnotationBindingTestCase {
@Test
public void testMappedSuperclass() {
buildMetadataSources( MyMappedSuperClass.class, MyEntity.class );
EntityBinding binding = getEntityBinding( MyEntity.class );
assertEquals( "Wrong entity name", MyEntity.class.getName(), binding.getEntity().getName() );
assertEquals(
"Wrong entity name",
MyMappedSuperClass.class.getName(),
binding.getEntity().getSuperType().getName()
);
assertTrue( binding.getEntity().getSuperType() instanceof Superclass );
AttributeBinding nameBinding = binding.getAttributeBinding( "name" );
assertNotNull( "the name attribute should be bound to the subclass", nameBinding );
AttributeBinding idBinding = binding.getEntityIdentifier().getValueBinding();
assertNotNull( "the id attribute should be bound", idBinding );
}
@Test
public void testNoEntity() {
buildMetadataSources( SubclassOfNoEntity.class, NoEntity.class );
EntityBinding binding = getEntityBinding( SubclassOfNoEntity.class );
assertEquals( "Wrong entity name", SubclassOfNoEntity.class.getName(), binding.getEntity().getName() );
assertEquals( "Wrong entity name", NoEntity.class.getName(), binding.getEntity().getSuperType().getName() );
assertTrue( binding.getEntity().getSuperType() instanceof NonEntity );
}
@MappedSuperclass
class MyMappedSuperClass {
@Id
private int id;
String name;
int age;
}
@Entity
class MyEntity extends MyMappedSuperClass {
private Long count;
}
class NoEntity {
String name;
int age;
}
@Entity
class SubclassOfNoEntity extends NoEntity {
@Id
private int id;
}
}

View File

@ -71,7 +71,7 @@ public class GenericTypeDiscoveryTest extends BaseAnnotationIndexTestCase {
info = configuredClass.getClassInfo();
assertEquals( "wrong class", DotName.createSimple( PricedStuff.class.getName() ), info.name() );
assertFalse(
"PricedStuff should not mapped properties", configuredClass.getMappedAttributes().iterator().hasNext()
"PricedStuff should not mapped properties", configuredClass.getSimpleAttributes().iterator().hasNext()
);
assertTrue( iter.hasNext() );
@ -88,7 +88,7 @@ public class GenericTypeDiscoveryTest extends BaseAnnotationIndexTestCase {
configuredClass = iter.next();
info = configuredClass.getClassInfo();
assertEquals( "wrong class", DotName.createSimple( Paper.class.getName() ), info.name() );
assertFalse( "Paper should not mapped properties", configuredClass.getMappedAttributes().iterator().hasNext() );
assertFalse( "Paper should not mapped properties", configuredClass.getSimpleAttributes().iterator().hasNext() );
assertFalse( iter.hasNext() );
}