HHH-6173 making ConfiguredClass a base class for EnityClass and EmbeddedClass
This commit is contained in:
parent
33a4694fea
commit
fcbca08a1f
|
@ -29,21 +29,23 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.jboss.jandex.Index;
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.internal.CoreMessageLogger;
|
||||
import org.jboss.jandex.Index;
|
||||
|
||||
import org.hibernate.metamodel.MetadataSources;
|
||||
import org.hibernate.metamodel.source.annotation.xml.XMLEntityMappings;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.entity.EntityBinder;
|
||||
import org.hibernate.metamodel.source.annotations.entity.EntityClass;
|
||||
import org.hibernate.metamodel.source.annotations.global.FetchProfileBinder;
|
||||
import org.hibernate.metamodel.source.annotations.global.FilterDefBinder;
|
||||
import org.hibernate.metamodel.source.annotations.global.IdGeneratorBinder;
|
||||
import org.hibernate.metamodel.source.annotations.global.QueryBinder;
|
||||
import org.hibernate.metamodel.source.annotations.global.TypeDefBinder;
|
||||
import org.hibernate.metamodel.source.annotations.global.FetchProfileBinder;
|
||||
import org.hibernate.metamodel.source.annotations.global.TableBinder;
|
||||
import org.hibernate.metamodel.source.annotations.global.TypeDefBinder;
|
||||
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
|
||||
import org.hibernate.metamodel.source.annotations.xml.OrmXmlParser;
|
||||
import org.hibernate.metamodel.source.internal.JaxbRoot;
|
||||
|
@ -52,9 +54,6 @@ import org.hibernate.metamodel.source.spi.Binder;
|
|||
import org.hibernate.metamodel.source.spi.MetadataImplementor;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
||||
import org.jboss.jandex.Indexer;
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
@ -63,7 +62,10 @@ import org.jboss.logging.Logger;
|
|||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class AnnotationBinder implements Binder {
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger( CoreMessageLogger.class, AnnotationBinder.class.getName() );
|
||||
private static final CoreMessageLogger LOG = Logger.getMessageLogger(
|
||||
CoreMessageLogger.class,
|
||||
AnnotationBinder.class.getName()
|
||||
);
|
||||
|
||||
private final MetadataImplementor metadata;
|
||||
|
||||
|
@ -75,7 +77,7 @@ public class AnnotationBinder implements Binder {
|
|||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings( {"unchecked"})
|
||||
@SuppressWarnings( { "unchecked" })
|
||||
public void prepare(MetadataSources sources) {
|
||||
// create a jandex index from the annotated classes
|
||||
Indexer indexer = new Indexer();
|
||||
|
@ -113,7 +115,7 @@ public class AnnotationBinder implements Binder {
|
|||
}
|
||||
}
|
||||
|
||||
private ClassLoaderService classLoaderService(){
|
||||
private ClassLoaderService classLoaderService() {
|
||||
if ( classLoaderService == null ) {
|
||||
classLoaderService = metadata.getServiceRegistry().getService( ClassLoaderService.class );
|
||||
}
|
||||
|
@ -122,12 +124,12 @@ public class AnnotationBinder implements Binder {
|
|||
|
||||
@Override
|
||||
public void bindIndependentMetadata(MetadataSources sources) {
|
||||
TypeDefBinder.bind( metadata, index );
|
||||
TypeDefBinder.bind( metadata, index );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bindTypeDependentMetadata(MetadataSources sources) {
|
||||
IdGeneratorBinder.bind( metadata, index );
|
||||
IdGeneratorBinder.bind( metadata, index );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -139,9 +141,9 @@ public class AnnotationBinder implements Binder {
|
|||
|
||||
// now we process each hierarchy one at the time
|
||||
for ( ConfiguredClassHierarchy hierarchy : hierarchies ) {
|
||||
for ( ConfiguredClass configuredClass : hierarchy ) {
|
||||
LOG.bindingEntityFromAnnotatedClass( configuredClass.getName() );
|
||||
EntityBinder entityBinder = new EntityBinder( metadata, configuredClass );
|
||||
for ( EntityClass entityClass : hierarchy ) {
|
||||
LOG.bindingEntityFromAnnotatedClass( entityClass.getName() );
|
||||
EntityBinder entityBinder = new EntityBinder( metadata, entityClass );
|
||||
entityBinder.bind();
|
||||
}
|
||||
}
|
||||
|
@ -150,9 +152,9 @@ public class AnnotationBinder implements Binder {
|
|||
@Override
|
||||
public void bindMappingDependentMetadata(MetadataSources sources) {
|
||||
TableBinder.bind( metadata, index );
|
||||
FetchProfileBinder.bind( metadata, index );
|
||||
QueryBinder.bind( metadata, index );
|
||||
FilterDefBinder.bind( metadata, index );
|
||||
FetchProfileBinder.bind( metadata, index );
|
||||
QueryBinder.bind( metadata, index );
|
||||
FilterDefBinder.bind( metadata, index );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,12 @@
|
|||
package org.hibernate.metamodel.source.annotations.entity;
|
||||
|
||||
|
||||
import com.fasterxml.classmate.ResolvedTypeWithMembers;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
import org.jboss.jandex.DotName;
|
||||
import org.jboss.jandex.Index;
|
||||
|
||||
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
||||
|
@ -51,6 +55,17 @@ public class AnnotationBindingContext {
|
|||
}
|
||||
return classLoaderService;
|
||||
}
|
||||
|
||||
public ClassInfo getClassInfo(String className) {
|
||||
DotName dotName = DotName.createSimple( className );
|
||||
return index.getClassByName( dotName );
|
||||
}
|
||||
|
||||
public ResolvedTypeWithMembers resolveType(String className) {
|
||||
// the resolved type for the top level class in the hierarchy
|
||||
Class<?> clazz = classLoaderService().classForName( className );
|
||||
return ReflectionHelper.resolveMemberTypes( clazz );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import java.lang.reflect.Type;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -42,7 +43,6 @@ 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.DotName;
|
||||
import org.jboss.jandex.FieldInfo;
|
||||
|
@ -51,23 +51,16 @@ import org.jboss.jandex.MethodInfo;
|
|||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.HibernateException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.metamodel.binding.InheritanceType;
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
||||
|
||||
/**
|
||||
* Represents an entity, mapped superclass or component configured via annotations/xml.
|
||||
* Base class for a configured entity, mapped super class or embeddable
|
||||
*
|
||||
* @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;
|
||||
|
||||
/**
|
||||
* The Jandex class info for this configured class. Provides access to the annotation defined on this configured class.
|
||||
*/
|
||||
|
@ -78,43 +71,40 @@ public class ConfiguredClass {
|
|||
*/
|
||||
private final Class<?> clazz;
|
||||
|
||||
private final boolean isRoot;
|
||||
/**
|
||||
* The default access type for this entity
|
||||
*/
|
||||
private final AccessType classAccessType;
|
||||
private final AccessType hierarchyAccessType;
|
||||
|
||||
private final InheritanceType inheritanceType;
|
||||
private final boolean hasOwnTable;
|
||||
private final String primaryTableName;
|
||||
|
||||
/**
|
||||
* The type of configured class, entity, mapped super class, embeddable, ...
|
||||
*/
|
||||
private final ConfiguredClassType configuredClassType;
|
||||
private final IdType idType;
|
||||
|
||||
/**
|
||||
* The mapped attributes for entity
|
||||
*/
|
||||
private final Map<String, MappedAttribute> mappedAttributes;
|
||||
|
||||
/**
|
||||
* The embedded classes for this entity
|
||||
*/
|
||||
private final Map<String, EmbeddedClass> embeddedClasses = new HashMap<String, EmbeddedClass>();
|
||||
|
||||
private final Set<String> transientFieldNames = new HashSet<String>();
|
||||
private final Set<String> transientMethodNames = new HashSet<String>();
|
||||
|
||||
private final AnnotationBindingContext context;
|
||||
|
||||
public ConfiguredClass(ClassInfo info,
|
||||
ConfiguredClass parent,
|
||||
AccessType hierarchyAccessType,
|
||||
InheritanceType inheritanceType,
|
||||
public ConfiguredClass(ClassInfo classInfo,
|
||||
AccessType defaultAccessType,
|
||||
ResolvedTypeWithMembers resolvedType,
|
||||
AnnotationBindingContext context) {
|
||||
this.context = context;
|
||||
this.classInfo = info;
|
||||
this.parent = parent;
|
||||
this.isRoot = parent == null;
|
||||
this.hierarchyAccessType = hierarchyAccessType;
|
||||
this.inheritanceType = inheritanceType;
|
||||
this.clazz = context.classLoaderService().classForName( info.toString() );
|
||||
|
||||
this.classInfo = classInfo;
|
||||
this.clazz = context.classLoaderService().classForName( classInfo.toString() );
|
||||
this.configuredClassType = determineType();
|
||||
this.classAccessType = determineClassAccessType();
|
||||
this.idType = determineIdType();
|
||||
|
||||
this.hasOwnTable = definesItsOwnTable();
|
||||
this.primaryTableName = determinePrimaryTableName();
|
||||
this.classAccessType = determineClassAccessType( defaultAccessType );
|
||||
|
||||
// find transient field and method names
|
||||
findTransientFieldAndMethodNames();
|
||||
|
@ -133,42 +123,26 @@ public class ConfiguredClass {
|
|||
return clazz.getName();
|
||||
}
|
||||
|
||||
public Class<?> getConfiguredClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public ClassInfo getClassInfo() {
|
||||
return classInfo;
|
||||
}
|
||||
|
||||
public ConfiguredClass getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public boolean isRoot() {
|
||||
return isRoot;
|
||||
}
|
||||
|
||||
public ConfiguredClassType getConfiguredClassType() {
|
||||
return configuredClassType;
|
||||
}
|
||||
|
||||
public InheritanceType getInheritanceType() {
|
||||
return inheritanceType;
|
||||
}
|
||||
|
||||
public IdType getIdType() {
|
||||
return idType;
|
||||
}
|
||||
|
||||
public boolean hasOwnTable() {
|
||||
return hasOwnTable;
|
||||
}
|
||||
|
||||
public String getPrimaryTableName() {
|
||||
return primaryTableName;
|
||||
}
|
||||
|
||||
public Iterable<MappedAttribute> getMappedAttributes() {
|
||||
return mappedAttributes.values();
|
||||
}
|
||||
|
||||
public Iterable<EmbeddedClass> getEmbeddedClasses() {
|
||||
return embeddedClasses.values();
|
||||
}
|
||||
|
||||
public MappedAttribute getMappedProperty(String propertyName) {
|
||||
return mappedAttributes.get( propertyName );
|
||||
}
|
||||
|
@ -177,11 +151,12 @@ public class ConfiguredClass {
|
|||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append( "ConfiguredClass" );
|
||||
sb.append( "{clazz=" ).append( clazz.getSimpleName() );
|
||||
sb.append( ", type=" ).append( configuredClassType );
|
||||
sb.append( "{clazz=" ).append( clazz );
|
||||
sb.append( ", classAccessType=" ).append( classAccessType );
|
||||
sb.append( ", isRoot=" ).append( isRoot );
|
||||
sb.append( ", inheritanceType=" ).append( inheritanceType );
|
||||
sb.append( ", configuredClassType=" ).append( configuredClassType );
|
||||
sb.append( ", mappedAttributes=" ).append( mappedAttributes );
|
||||
sb.append( ", transientFieldNames=" ).append( transientFieldNames );
|
||||
sb.append( ", transientMethodNames=" ).append( transientMethodNames );
|
||||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
|
@ -210,9 +185,9 @@ public class ConfiguredClass {
|
|||
return ConfiguredClassType.NON_ENTITY;
|
||||
}
|
||||
|
||||
private AccessType determineClassAccessType() {
|
||||
private AccessType determineClassAccessType(AccessType defaultAccessType) {
|
||||
// default to the hierarchy access type to start with
|
||||
AccessType accessType = hierarchyAccessType;
|
||||
AccessType accessType = defaultAccessType;
|
||||
|
||||
AnnotationInstance accessAnnotation = JandexHelper.getSingleAnnotation( classInfo, JPADotNames.ACCESS );
|
||||
if ( accessAnnotation != null ) {
|
||||
|
@ -377,7 +352,7 @@ public class ConfiguredClass {
|
|||
}
|
||||
|
||||
private MappedAttribute createMappedProperty(Member member, ResolvedTypeWithMembers resolvedType) {
|
||||
final String name = ReflectionHelper.getPropertyName( member );
|
||||
final String attributeName = ReflectionHelper.getPropertyName( member );
|
||||
ResolvedMember[] resolvedMembers;
|
||||
if ( member instanceof Field ) {
|
||||
resolvedMembers = resolvedType.getMemberFields();
|
||||
|
@ -385,7 +360,7 @@ public class ConfiguredClass {
|
|||
else {
|
||||
resolvedMembers = resolvedType.getMemberMethods();
|
||||
}
|
||||
final Type type = findResolvedType( member.getName(), resolvedMembers );
|
||||
final Class<?> type = (Class<?>) findResolvedType( member.getName(), resolvedMembers );
|
||||
final Map<DotName, List<AnnotationInstance>> annotations = JandexHelper.getMemberAnnotations(
|
||||
classInfo, member.getName()
|
||||
);
|
||||
|
@ -394,16 +369,34 @@ public class ConfiguredClass {
|
|||
AttributeType attributeType = determineAttributeType( annotations );
|
||||
switch ( attributeType ) {
|
||||
case BASIC: {
|
||||
attribute = SimpleAttribute.createSimpleAttribute( name, ( (Class) type ).getName(), annotations );
|
||||
attribute = SimpleAttribute.createSimpleAttribute( attributeName, type.getName(), annotations );
|
||||
break;
|
||||
}
|
||||
case EMBEDDED: {
|
||||
throw new HibernateException( "foo" );
|
||||
ClassInfo embeddableClassInfo = context.getClassInfo( type.getName() );
|
||||
if ( classInfo == null ) {
|
||||
String msg = String.format(
|
||||
"Attribute %s of entity %s is annotated with @Embedded, but no embeddable configuration for type %s can be found.",
|
||||
attributeName,
|
||||
getName(),
|
||||
type.getName()
|
||||
);
|
||||
throw new AnnotationException( msg );
|
||||
}
|
||||
|
||||
EmbeddedClass embeddedClass = new EmbeddedClass(
|
||||
embeddableClassInfo,
|
||||
classAccessType,
|
||||
context.resolveType( type.getName() ),
|
||||
context
|
||||
);
|
||||
|
||||
embeddedClasses.put( attributeName, embeddedClass );
|
||||
}
|
||||
// TODO handle the different association types
|
||||
default: {
|
||||
attribute = AssociationAttribute.createAssociationAttribute(
|
||||
name, ( (Class) type ).getName(), attributeType, annotations
|
||||
attributeName, ( (Class) type ).getName(), attributeType, annotations
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -487,72 +480,4 @@ public class 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() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( InheritanceType.SINGLE_TABLE.equals( inheritanceType ) ) {
|
||||
return isRoot();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String determinePrimaryTableName() {
|
||||
String tableName = null;
|
||||
if ( hasOwnTable() ) {
|
||||
tableName = clazz.getSimpleName();
|
||||
AnnotationInstance tableAnnotation = JandexHelper.getSingleAnnotation(
|
||||
classInfo, JPADotNames.TABLE
|
||||
);
|
||||
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.getConfiguredClassType().equals( ConfiguredClassType.MAPPED_SUPERCLASS )
|
||||
&& !parent.getConfiguredClassType().equals( ConfiguredClassType.EMBEDDABLE ) ) {
|
||||
tableName = parent.getPrimaryTableName();
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
private IdType determineIdType() {
|
||||
List<AnnotationInstance> idAnnotations = getClassInfo().annotations().get( JPADotNames.ENTITY );
|
||||
List<AnnotationInstance> embeddedIdAnnotations = getClassInfo()
|
||||
.annotations()
|
||||
.get( JPADotNames.EMBEDDED_ID );
|
||||
|
||||
if ( idAnnotations != null && embeddedIdAnnotations != null ) {
|
||||
throw new MappingException(
|
||||
"@EmbeddedId and @Id cannot be used together. Check the configuration for " + getName() + "."
|
||||
);
|
||||
}
|
||||
|
||||
if ( embeddedIdAnnotations != null ) {
|
||||
if ( embeddedIdAnnotations.size() == 1 ) {
|
||||
return IdType.EMBEDDED;
|
||||
}
|
||||
else {
|
||||
throw new AnnotationException( "Multiple @EmbeddedId annotations are not allowed" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( idAnnotations != null ) {
|
||||
if ( idAnnotations.size() == 1 ) {
|
||||
return IdType.SIMPLE;
|
||||
}
|
||||
else {
|
||||
return IdType.COMPOSED;
|
||||
}
|
||||
}
|
||||
return IdType.NONE;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,18 +38,16 @@ import org.hibernate.AnnotationException;
|
|||
import org.hibernate.metamodel.binding.InheritanceType;
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
||||
/**
|
||||
* Contains information about the access and inheritance type for all classes within a class hierarchy.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
||||
public class ConfiguredClassHierarchy implements Iterable<EntityClass> {
|
||||
private final AccessType defaultAccessType;
|
||||
private final InheritanceType inheritanceType;
|
||||
private final List<ConfiguredClass> configuredClasses;
|
||||
private final List<EntityClass> entityClasses;
|
||||
|
||||
public static ConfiguredClassHierarchy create(List<ClassInfo> classes, AnnotationBindingContext context) {
|
||||
return new ConfiguredClassHierarchy( classes, context );
|
||||
|
@ -60,17 +58,18 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
|||
inheritanceType = determineInheritanceType( classes );
|
||||
|
||||
// the resolved type for the top level class in the hierarchy
|
||||
Class<?> clazz = context.classLoaderService().classForName( classes.get( classes.size() - 1 ).name().toString() );
|
||||
ResolvedTypeWithMembers resolvedType = ReflectionHelper.resolveMemberTypes( clazz );
|
||||
ResolvedTypeWithMembers resolvedType = context.resolveType(
|
||||
classes.get( classes.size() - 1 ).name().toString()
|
||||
);
|
||||
|
||||
configuredClasses = new ArrayList<ConfiguredClass>();
|
||||
ConfiguredClass parent = null;
|
||||
entityClasses = new ArrayList<EntityClass>();
|
||||
EntityClass parent = null;
|
||||
for ( ClassInfo info : classes ) {
|
||||
ConfiguredClass configuredClass = new ConfiguredClass(
|
||||
EntityClass entityClass = new EntityClass(
|
||||
info, parent, defaultAccessType, inheritanceType, resolvedType, context
|
||||
);
|
||||
configuredClasses.add( configuredClass );
|
||||
parent = configuredClass;
|
||||
entityClasses.add( entityClass );
|
||||
parent = entityClass;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,8 +84,8 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
|||
/**
|
||||
* @return An iterator iterating in top down manner over the configured classes in this hierarchy.
|
||||
*/
|
||||
public Iterator<ConfiguredClass> iterator() {
|
||||
return configuredClasses.iterator();
|
||||
public Iterator<EntityClass> iterator() {
|
||||
return entityClasses.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -94,7 +93,7 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
|||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append( "ConfiguredClassHierarchy" );
|
||||
sb.append( "{defaultAccessType=" ).append( defaultAccessType );
|
||||
sb.append( ", configuredClasses=" ).append( configuredClasses );
|
||||
sb.append( ", configuredClasses=" ).append( entityClasses );
|
||||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* 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.entity;
|
||||
|
||||
import javax.persistence.AccessType;
|
||||
|
||||
import com.fasterxml.classmate.ResolvedTypeWithMembers;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class EmbeddedClass extends ConfiguredClass {
|
||||
public EmbeddedClass(ClassInfo classInfo,
|
||||
AccessType defaultAccessType,
|
||||
ResolvedTypeWithMembers resolvedType,
|
||||
AnnotationBindingContext context) {
|
||||
super( classInfo, defaultAccessType, resolvedType, context );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,19 +78,19 @@ import org.hibernate.persister.entity.EntityPersister;
|
|||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class EntityBinder {
|
||||
private final ConfiguredClass configuredClass;
|
||||
private final EntityClass entityClass;
|
||||
private final MetadataImplementor meta;
|
||||
|
||||
private Schema.Name schemaName;
|
||||
|
||||
public EntityBinder(MetadataImplementor metadata, ConfiguredClass configuredClass) {
|
||||
this.configuredClass = configuredClass;
|
||||
public EntityBinder(MetadataImplementor metadata, EntityClass entityClass) {
|
||||
this.entityClass = entityClass;
|
||||
this.meta = metadata;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
EntityBinding entityBinding = new EntityBinding();
|
||||
EntityBindingStateImpl entityBindingState = new EntityBindingStateImpl( getSuperType(), configuredClass );
|
||||
EntityBindingStateImpl entityBindingState = new EntityBindingStateImpl( getSuperType(), entityClass );
|
||||
|
||||
bindJpaEntityAnnotation( entityBindingState );
|
||||
bindHibernateEntityAnnotation( entityBindingState ); // optional hibernate specific @org.hibernate.annotations.Entity
|
||||
|
@ -113,7 +113,7 @@ public class EntityBinder {
|
|||
bindInheritance( entityBinding );
|
||||
|
||||
// take care of the id, attributes and relations
|
||||
if ( configuredClass.isRoot() ) {
|
||||
if ( entityClass.isRoot() ) {
|
||||
bindId( entityBinding );
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindTableUniqueConstraints(EntityBinding entityBinding) {
|
||||
AnnotationInstance tableAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(),
|
||||
entityClass.getClassInfo(),
|
||||
JPADotNames.TABLE
|
||||
);
|
||||
if ( tableAnnotation == null ) {
|
||||
|
@ -163,8 +163,8 @@ public class EntityBinder {
|
|||
}
|
||||
|
||||
private void bindInheritance(EntityBinding entityBinding) {
|
||||
entityBinding.setInheritanceType( configuredClass.getInheritanceType() );
|
||||
switch ( configuredClass.getInheritanceType() ) {
|
||||
entityBinding.setInheritanceType( entityClass.getInheritanceType() );
|
||||
switch ( entityClass.getInheritanceType() ) {
|
||||
case SINGLE_TABLE: {
|
||||
bindDiscriminatorColumn( entityBinding );
|
||||
break;
|
||||
|
@ -185,7 +185,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindDiscriminatorColumn(EntityBinding entityBinding) {
|
||||
final Map<DotName, List<AnnotationInstance>> typeAnnotations = JandexHelper.getTypeAnnotations(
|
||||
configuredClass.getClassInfo()
|
||||
entityClass.getClassInfo()
|
||||
);
|
||||
SimpleAttribute discriminatorAttribute = SimpleAttribute.createDiscriminatorAttribute( typeAnnotations );
|
||||
|
||||
|
@ -198,7 +198,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindWhereFilter(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance whereAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.WHERE
|
||||
entityClass.getClassInfo(), HibernateDotNames.WHERE
|
||||
);
|
||||
if ( whereAnnotation != null ) {
|
||||
// no null check needed, it is a required attribute
|
||||
|
@ -209,7 +209,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindHibernateCaching(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance cacheAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.CACHE
|
||||
entityClass.getClassInfo(), HibernateDotNames.CACHE
|
||||
);
|
||||
if ( cacheAnnotation == null ) {
|
||||
return;
|
||||
|
@ -248,7 +248,7 @@ public class EntityBinder {
|
|||
// This is currently not supported (HF)
|
||||
private void bindJpaCaching(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance cacheAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), JPADotNames.CACHEABLE
|
||||
entityClass.getClassInfo(), JPADotNames.CACHEABLE
|
||||
);
|
||||
|
||||
boolean cacheable = true; // true is the default
|
||||
|
@ -286,7 +286,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindProxy(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance proxyAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.PROXY
|
||||
entityClass.getClassInfo(), HibernateDotNames.PROXY
|
||||
);
|
||||
boolean lazy = true;
|
||||
String proxyInterfaceClass = null;
|
||||
|
@ -309,7 +309,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindSynchronize(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance synchronizeAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.SYNCHRONIZE
|
||||
entityClass.getClassInfo(), HibernateDotNames.SYNCHRONIZE
|
||||
);
|
||||
|
||||
if ( synchronizeAnnotation != null ) {
|
||||
|
@ -322,22 +322,22 @@ public class EntityBinder {
|
|||
|
||||
private void bindCustomSQL(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance sqlInsertAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.SQL_INSERT
|
||||
entityClass.getClassInfo(), HibernateDotNames.SQL_INSERT
|
||||
);
|
||||
entityBindingState.setCustomInsert( createCustomSQL( sqlInsertAnnotation ) );
|
||||
|
||||
AnnotationInstance sqlUpdateAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.SQL_UPDATE
|
||||
entityClass.getClassInfo(), HibernateDotNames.SQL_UPDATE
|
||||
);
|
||||
entityBindingState.setCustomUpdate( createCustomSQL( sqlUpdateAnnotation ) );
|
||||
|
||||
AnnotationInstance sqlDeleteAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.SQL_DELETE
|
||||
entityClass.getClassInfo(), HibernateDotNames.SQL_DELETE
|
||||
);
|
||||
entityBindingState.setCustomDelete( createCustomSQL( sqlDeleteAnnotation ) );
|
||||
|
||||
AnnotationInstance sqlDeleteAllAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.SQL_DELETE_ALL
|
||||
entityClass.getClassInfo(), HibernateDotNames.SQL_DELETE_ALL
|
||||
);
|
||||
if ( sqlDeleteAllAnnotation != null ) {
|
||||
entityBindingState.setCustomDelete( createCustomSQL( sqlDeleteAllAnnotation ) );
|
||||
|
@ -371,7 +371,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindRowId(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance rowIdAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.ROW_ID
|
||||
entityClass.getClassInfo(), HibernateDotNames.ROW_ID
|
||||
);
|
||||
|
||||
if ( rowIdAnnotation != null ) {
|
||||
|
@ -381,7 +381,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindBatchSize(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance batchSizeAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.BATCH_SIZE
|
||||
entityClass.getClassInfo(), HibernateDotNames.BATCH_SIZE
|
||||
);
|
||||
|
||||
if ( batchSizeAnnotation != null ) {
|
||||
|
@ -401,7 +401,7 @@ public class EntityBinder {
|
|||
String catalog = null;
|
||||
|
||||
AnnotationInstance tableAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), JPADotNames.TABLE
|
||||
entityClass.getClassInfo(), JPADotNames.TABLE
|
||||
);
|
||||
if ( tableAnnotation != null ) {
|
||||
AnnotationValue schemaValue = tableAnnotation.value( "schema" );
|
||||
|
@ -416,7 +416,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindTable(EntityBinding entityBinding) {
|
||||
final Schema schema = meta.getDatabase().getSchema( schemaName );
|
||||
final Identifier tableName = Identifier.toIdentifier( configuredClass.getPrimaryTableName() );
|
||||
final Identifier tableName = Identifier.toIdentifier( entityClass.getPrimaryTableName() );
|
||||
org.hibernate.metamodel.relational.Table table = schema.getTable( tableName );
|
||||
if ( table == null ) {
|
||||
table = schema.createTable( tableName );
|
||||
|
@ -424,7 +424,7 @@ public class EntityBinder {
|
|||
entityBinding.setBaseTable( table );
|
||||
|
||||
AnnotationInstance checkAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.CHECK
|
||||
entityClass.getClassInfo(), HibernateDotNames.CHECK
|
||||
);
|
||||
if ( checkAnnotation != null ) {
|
||||
table.addCheckConstraint( checkAnnotation.value( "constraints" ).asString() );
|
||||
|
@ -432,7 +432,7 @@ public class EntityBinder {
|
|||
}
|
||||
|
||||
private void bindId(EntityBinding entityBinding) {
|
||||
switch ( configuredClass.getIdType() ) {
|
||||
switch ( entityClass.getIdType() ) {
|
||||
case SIMPLE: {
|
||||
bindSingleIdAnnotation( entityBinding );
|
||||
break;
|
||||
|
@ -453,11 +453,11 @@ public class EntityBinder {
|
|||
|
||||
private void bindJpaEntityAnnotation(EntityBindingStateImpl entityBindingState) {
|
||||
AnnotationInstance jpaEntityAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), JPADotNames.ENTITY
|
||||
entityClass.getClassInfo(), JPADotNames.ENTITY
|
||||
);
|
||||
String name;
|
||||
if ( jpaEntityAnnotation.value( "name" ) == null ) {
|
||||
name = configuredClass.getName();
|
||||
name = entityClass.getName();
|
||||
}
|
||||
else {
|
||||
name = jpaEntityAnnotation.value( "name" ).asString();
|
||||
|
@ -467,11 +467,11 @@ public class EntityBinder {
|
|||
|
||||
private void bindSingleIdAnnotation(EntityBinding entityBinding) {
|
||||
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), JPADotNames.ID
|
||||
entityClass.getClassInfo(), JPADotNames.ID
|
||||
);
|
||||
|
||||
String idName = JandexHelper.getPropertyName( idAnnotation.target() );
|
||||
MappedAttribute idAttribute = configuredClass.getMappedProperty( idName );
|
||||
MappedAttribute idAttribute = entityClass.getMappedProperty( idName );
|
||||
if ( !( idAttribute instanceof SimpleAttribute ) ) {
|
||||
throw new AssertionFailure( "Unexpected attribute type for id attribute" );
|
||||
}
|
||||
|
@ -487,7 +487,7 @@ public class EntityBinder {
|
|||
|
||||
private void bindSingleIdGeneratedValue(EntityBinding entityBinding, String idPropertyName) {
|
||||
AnnotationInstance generatedValueAnn = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), JPADotNames.GENERATED_VALUE
|
||||
entityClass.getClassInfo(), JPADotNames.GENERATED_VALUE
|
||||
);
|
||||
if ( generatedValueAnn == null ) {
|
||||
return;
|
||||
|
@ -498,7 +498,7 @@ public class EntityBinder {
|
|||
throw new AssertionFailure(
|
||||
String.format(
|
||||
"Attribute[%s.%s] with @GeneratedValue doesn't have a @Id.",
|
||||
configuredClass.getName(),
|
||||
entityClass.getName(),
|
||||
idPropertyName
|
||||
)
|
||||
);
|
||||
|
@ -511,7 +511,7 @@ public class EntityBinder {
|
|||
throw new MappingException(
|
||||
String.format(
|
||||
"@GeneratedValue on %s.%s refering an undefined generator [%s]",
|
||||
configuredClass.getName(),
|
||||
entityClass.getName(),
|
||||
idName,
|
||||
generator
|
||||
)
|
||||
|
@ -533,7 +533,7 @@ public class EntityBinder {
|
|||
throw new MappingException(
|
||||
String.format(
|
||||
"Inconsistent Id Generation strategy of @GeneratedValue on %s.%s",
|
||||
configuredClass.getName(),
|
||||
entityClass.getName(),
|
||||
idName
|
||||
)
|
||||
);
|
||||
|
@ -544,9 +544,8 @@ public class EntityBinder {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private void bindAttributes(EntityBinding entityBinding) {
|
||||
for ( MappedAttribute mappedAttribute : configuredClass.getMappedAttributes() ) {
|
||||
for ( MappedAttribute mappedAttribute : entityClass.getMappedAttributes() ) {
|
||||
if ( mappedAttribute instanceof AssociationAttribute ) {
|
||||
bindAssociationAttribute( entityBinding, (AssociationAttribute) mappedAttribute );
|
||||
}
|
||||
|
@ -554,6 +553,17 @@ public class EntityBinder {
|
|||
bindSingleMappedAttribute( entityBinding, (SimpleAttribute) mappedAttribute );
|
||||
}
|
||||
}
|
||||
|
||||
for ( EmbeddedClass embeddedClass : entityClass.getEmbeddedClasses() ) {
|
||||
for ( MappedAttribute mappedAttribute : embeddedClass.getMappedAttributes() ) {
|
||||
if ( mappedAttribute instanceof AssociationAttribute ) {
|
||||
bindAssociationAttribute( entityBinding, (AssociationAttribute) mappedAttribute );
|
||||
}
|
||||
else {
|
||||
bindSingleMappedAttribute( entityBinding, (SimpleAttribute) mappedAttribute );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bindAssociationAttribute(EntityBinding entityBinding, AssociationAttribute associationAttribute) {
|
||||
|
@ -568,7 +578,7 @@ public class EntityBinder {
|
|||
manyToOneAttributeBinding.initialize( bindingState );
|
||||
|
||||
ManyToOneRelationalStateImpl relationalState = new ManyToOneRelationalStateImpl();
|
||||
if ( configuredClass.hasOwnTable() ) {
|
||||
if ( entityClass.hasOwnTable() ) {
|
||||
ColumnRelationalStateImpl columnRelationsState = new ColumnRelationalStateImpl(
|
||||
associationAttribute, meta
|
||||
);
|
||||
|
@ -609,7 +619,7 @@ public class EntityBinder {
|
|||
attributeBinding.initialize( bindingState );
|
||||
}
|
||||
|
||||
if ( configuredClass.hasOwnTable() ) {
|
||||
if ( entityClass.hasOwnTable() ) {
|
||||
ColumnRelationalStateImpl columnRelationsState = new ColumnRelationalStateImpl(
|
||||
simpleAttribute, meta
|
||||
);
|
||||
|
@ -630,7 +640,7 @@ public class EntityBinder {
|
|||
OptimisticLockType optimisticLock = OptimisticLockType.VERSION;
|
||||
|
||||
AnnotationInstance hibernateEntityAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.ENTITY
|
||||
entityClass.getClassInfo(), HibernateDotNames.ENTITY
|
||||
);
|
||||
|
||||
if ( hibernateEntityAnnotation != null ) {
|
||||
|
@ -668,7 +678,7 @@ public class EntityBinder {
|
|||
|
||||
// also check for the immutable annotation
|
||||
AnnotationInstance immutableAnnotation = JandexHelper.getSingleAnnotation(
|
||||
configuredClass.getClassInfo(), HibernateDotNames.IMMUTABLE
|
||||
entityClass.getClassInfo(), HibernateDotNames.IMMUTABLE
|
||||
);
|
||||
if ( immutableAnnotation != null ) {
|
||||
mutable = false;
|
||||
|
@ -683,7 +693,7 @@ public class EntityBinder {
|
|||
}
|
||||
|
||||
private Hierarchical getSuperType() {
|
||||
ConfiguredClass parent = configuredClass.getParent();
|
||||
ConfiguredClass parent = entityClass.getParent();
|
||||
if ( parent == null ) {
|
||||
return null;
|
||||
}
|
||||
|
@ -691,7 +701,7 @@ public class EntityBinder {
|
|||
EntityBinding parentBinding = meta.getEntityBinding( parent.getName() );
|
||||
if ( parentBinding == null ) {
|
||||
throw new AssertionFailure(
|
||||
"Parent entity " + parent.getName() + " of entity " + configuredClass.getName() + " not yet created!"
|
||||
"Parent entity " + parent.getName() + " of entity " + entityClass.getName() + " not yet created!"
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* 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.entity;
|
||||
|
||||
import java.util.List;
|
||||
import javax.persistence.AccessType;
|
||||
|
||||
import com.fasterxml.classmate.ResolvedTypeWithMembers;
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.AnnotationValue;
|
||||
import org.jboss.jandex.ClassInfo;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.MappingException;
|
||||
import org.hibernate.metamodel.binding.InheritanceType;
|
||||
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.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class EntityClass extends ConfiguredClass {
|
||||
/**
|
||||
* The parent of this configured class or {@code null} in case this configured class is the root of a hierarchy.
|
||||
*/
|
||||
private final EntityClass parent;
|
||||
|
||||
private final boolean isRoot;
|
||||
private final AccessType hierarchyAccessType;
|
||||
|
||||
private final InheritanceType inheritanceType;
|
||||
private final boolean hasOwnTable;
|
||||
private final String primaryTableName;
|
||||
|
||||
private final IdType idType;
|
||||
|
||||
public EntityClass(ClassInfo classInfo,
|
||||
EntityClass parent,
|
||||
AccessType hierarchyAccessType,
|
||||
InheritanceType inheritanceType,
|
||||
ResolvedTypeWithMembers resolvedType,
|
||||
AnnotationBindingContext context) {
|
||||
|
||||
super( classInfo, hierarchyAccessType, resolvedType, context );
|
||||
this.parent = parent;
|
||||
this.isRoot = parent == null;
|
||||
this.hierarchyAccessType = hierarchyAccessType;
|
||||
this.inheritanceType = inheritanceType;
|
||||
this.idType = determineIdType();
|
||||
|
||||
this.hasOwnTable = definesItsOwnTable();
|
||||
this.primaryTableName = determinePrimaryTableName();
|
||||
}
|
||||
|
||||
public EntityClass getParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
public boolean isRoot() {
|
||||
return isRoot;
|
||||
}
|
||||
|
||||
public InheritanceType getInheritanceType() {
|
||||
return inheritanceType;
|
||||
}
|
||||
|
||||
public IdType getIdType() {
|
||||
return idType;
|
||||
}
|
||||
|
||||
public boolean hasOwnTable() {
|
||||
return hasOwnTable;
|
||||
}
|
||||
|
||||
public String getPrimaryTableName() {
|
||||
return primaryTableName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append( "EntityClass" );
|
||||
sb.append( "{name=" ).append( getName() );
|
||||
sb.append( ", isRoot=" ).append( isRoot );
|
||||
sb.append( ", hierarchyAccessType=" ).append( hierarchyAccessType );
|
||||
sb.append( ", inheritanceType=" ).append( inheritanceType );
|
||||
sb.append( ", hasOwnTable=" ).append( hasOwnTable );
|
||||
sb.append( ", primaryTableName='" ).append( primaryTableName ).append( '\'' );
|
||||
sb.append( ", idType=" ).append( idType );
|
||||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private boolean definesItsOwnTable() {
|
||||
// mapped super classes and embeddables don't have their own tables
|
||||
if ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( getConfiguredClassType() ) || ConfiguredClassType.EMBEDDABLE
|
||||
.equals( getConfiguredClassType() ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( InheritanceType.SINGLE_TABLE.equals( inheritanceType ) ) {
|
||||
return isRoot();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String determinePrimaryTableName() {
|
||||
String tableName = null;
|
||||
if ( hasOwnTable() ) {
|
||||
tableName = getConfiguredClass().getSimpleName();
|
||||
AnnotationInstance tableAnnotation = JandexHelper.getSingleAnnotation(
|
||||
getClassInfo(), JPADotNames.TABLE
|
||||
);
|
||||
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.getConfiguredClassType().equals( ConfiguredClassType.MAPPED_SUPERCLASS )
|
||||
&& !parent.getConfiguredClassType().equals( ConfiguredClassType.EMBEDDABLE ) ) {
|
||||
tableName = parent.getPrimaryTableName();
|
||||
}
|
||||
return tableName;
|
||||
}
|
||||
|
||||
private IdType determineIdType() {
|
||||
List<AnnotationInstance> idAnnotations = getClassInfo().annotations().get( JPADotNames.ENTITY );
|
||||
List<AnnotationInstance> embeddedIdAnnotations = getClassInfo()
|
||||
.annotations()
|
||||
.get( JPADotNames.EMBEDDED_ID );
|
||||
|
||||
if ( idAnnotations != null && embeddedIdAnnotations != null ) {
|
||||
throw new MappingException(
|
||||
"@EmbeddedId and @Id cannot be used together. Check the configuration for " + getName() + "."
|
||||
);
|
||||
}
|
||||
|
||||
if ( embeddedIdAnnotations != null ) {
|
||||
if ( embeddedIdAnnotations.size() == 1 ) {
|
||||
return IdType.EMBEDDED;
|
||||
}
|
||||
else {
|
||||
throw new AnnotationException( "Multiple @EmbeddedId annotations are not allowed" );
|
||||
}
|
||||
}
|
||||
|
||||
if ( idAnnotations != null ) {
|
||||
if ( idAnnotations.size() == 1 ) {
|
||||
return IdType.SIMPLE;
|
||||
}
|
||||
else {
|
||||
return IdType.COMPOSED;
|
||||
}
|
||||
}
|
||||
return IdType.NONE;
|
||||
}
|
||||
}
|
|
@ -35,7 +35,7 @@ import org.hibernate.metamodel.binding.CustomSQL;
|
|||
import org.hibernate.metamodel.binding.InheritanceType;
|
||||
import org.hibernate.metamodel.binding.state.EntityBindingState;
|
||||
import org.hibernate.metamodel.domain.Hierarchical;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.EntityClass;
|
||||
import org.hibernate.metamodel.source.spi.MetaAttributeContext;
|
||||
import org.hibernate.persister.entity.EntityPersister;
|
||||
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||
|
@ -78,7 +78,7 @@ public class EntityBindingStateImpl implements EntityBindingState {
|
|||
|
||||
private Set<String> synchronizedTableNames;
|
||||
|
||||
public EntityBindingStateImpl(Hierarchical superType, ConfiguredClass configuredClass) {
|
||||
public EntityBindingStateImpl(Hierarchical superType, EntityClass configuredClass) {
|
||||
this.className = configuredClass.getName();
|
||||
this.superType = superType;
|
||||
this.isRoot = configuredClass.isRoot();
|
||||
|
|
|
@ -37,8 +37,8 @@ import org.jboss.jandex.Index;
|
|||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.entity.AnnotationBindingContext;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
||||
|
@ -95,7 +95,7 @@ public class ConfiguredClassHierarchyBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
AnnotationBindingContext context = new AnnotationBindingContext(index, serviceRegistry);
|
||||
AnnotationBindingContext context = new AnnotationBindingContext( index, serviceRegistry );
|
||||
Set<ConfiguredClassHierarchy> hierarchies = new HashSet<ConfiguredClassHierarchy>();
|
||||
List<List<ClassInfo>> processedList = new ArrayList<List<ClassInfo>>();
|
||||
for ( List<ClassInfo> classInfoList : processedClassInfos.values() ) {
|
||||
|
@ -121,18 +121,19 @@ public class ConfiguredClassHierarchyBuilder {
|
|||
AnnotationInstance mappedSuperClassAnnotation = JandexHelper.getSingleAnnotation(
|
||||
info, JPADotNames.MAPPED_SUPERCLASS
|
||||
);
|
||||
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 ) {
|
||||
// we are only interested in building the class hierarchies for @Entity or @MappedSuperclass
|
||||
if ( jpaEntityAnnotation == null && mappedSuperClassAnnotation == null ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// some sanity checks
|
||||
String className = info.toString();
|
||||
assertNotEntityAndMappedSuperClass( jpaEntityAnnotation, mappedSuperClassAnnotation, className );
|
||||
|
||||
AnnotationInstance embeddableAnnotation = JandexHelper.getSingleAnnotation(
|
||||
info, JPADotNames.EMBEDDABLE
|
||||
);
|
||||
assertNotEntityAndEmbeddable( jpaEntityAnnotation, embeddableAnnotation, className );
|
||||
|
||||
return isConfiguredClass;
|
||||
|
|
|
@ -31,7 +31,6 @@ import javax.persistence.Id;
|
|||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.metamodel.binding.EntityBinding;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
|
||||
|
@ -42,11 +41,10 @@ import static junit.framework.Assert.assertNotNull;
|
|||
*/
|
||||
public class EmbeddableBindingTests extends BaseAnnotationBindingTestCase {
|
||||
@Test
|
||||
@FailureExpected(jiraKey = "HHH6173", message = "Under construction")
|
||||
public void testEmbeddable() {
|
||||
buildMetadataSources( User.class );
|
||||
buildMetadataSources( User.class, Address.class );
|
||||
EntityBinding binding = getEntityBinding( User.class );
|
||||
assertNotNull( binding.getAttributeBinding( "address" ) );
|
||||
assertNotNull( binding.getAttributeBinding( "city" ) );
|
||||
}
|
||||
|
||||
@Entity
|
||||
|
|
|
@ -40,8 +40,6 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.metamodel.binding.InheritanceType;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
|
||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.service.ServiceRegistryBuilder;
|
||||
|
@ -91,28 +89,28 @@ public class TableNameTest extends BaseUnitTestCase {
|
|||
);
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
ConfiguredClass configuredClass = iter.next();
|
||||
ClassInfo info = configuredClass.getClassInfo();
|
||||
Iterator<EntityClass> iter = hierarchies.iterator().next().iterator();
|
||||
EntityClass entityClass = iter.next();
|
||||
ClassInfo info = entityClass.getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( A.class.getName() ), info.name() );
|
||||
assertTrue( configuredClass.hasOwnTable() );
|
||||
assertTrue( entityClass.hasOwnTable() );
|
||||
Assert.assertEquals(
|
||||
"wrong inheritance type", InheritanceType.SINGLE_TABLE, configuredClass.getInheritanceType()
|
||||
"wrong inheritance type", InheritanceType.SINGLE_TABLE, entityClass.getInheritanceType()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"wrong table name", "A", configuredClass.getPrimaryTableName()
|
||||
"wrong table name", "A", entityClass.getPrimaryTableName()
|
||||
);
|
||||
|
||||
assertTrue( iter.hasNext() );
|
||||
configuredClass = iter.next();
|
||||
info = configuredClass.getClassInfo();
|
||||
entityClass = iter.next();
|
||||
info = entityClass.getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( B.class.getName() ), info.name() );
|
||||
assertFalse( configuredClass.hasOwnTable() );
|
||||
assertFalse( entityClass.hasOwnTable() );
|
||||
Assert.assertEquals(
|
||||
"wrong inheritance type", InheritanceType.SINGLE_TABLE, configuredClass.getInheritanceType()
|
||||
"wrong inheritance type", InheritanceType.SINGLE_TABLE, entityClass.getInheritanceType()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"wrong table name", "A", configuredClass.getPrimaryTableName()
|
||||
"wrong table name", "A", entityClass.getPrimaryTableName()
|
||||
);
|
||||
|
||||
assertFalse( iter.hasNext() );
|
||||
|
@ -138,28 +136,28 @@ public class TableNameTest extends BaseUnitTestCase {
|
|||
);
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
ConfiguredClass configuredClass = iter.next();
|
||||
ClassInfo info = configuredClass.getClassInfo();
|
||||
Iterator<EntityClass> iter = hierarchies.iterator().next().iterator();
|
||||
EntityClass entityClass = iter.next();
|
||||
ClassInfo info = entityClass.getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( A.class.getName() ), info.name() );
|
||||
assertTrue( configuredClass.hasOwnTable() );
|
||||
assertTrue( entityClass.hasOwnTable() );
|
||||
Assert.assertEquals(
|
||||
"wrong inheritance type", InheritanceType.TABLE_PER_CLASS, configuredClass.getInheritanceType()
|
||||
"wrong inheritance type", InheritanceType.TABLE_PER_CLASS, entityClass.getInheritanceType()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"wrong table name", "A", configuredClass.getPrimaryTableName()
|
||||
"wrong table name", "A", entityClass.getPrimaryTableName()
|
||||
);
|
||||
|
||||
assertTrue( iter.hasNext() );
|
||||
configuredClass = iter.next();
|
||||
info = configuredClass.getClassInfo();
|
||||
entityClass = iter.next();
|
||||
info = entityClass.getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( B.class.getName() ), info.name() );
|
||||
assertTrue( configuredClass.hasOwnTable() );
|
||||
assertTrue( entityClass.hasOwnTable() );
|
||||
Assert.assertEquals(
|
||||
"wrong inheritance type", InheritanceType.TABLE_PER_CLASS, configuredClass.getInheritanceType()
|
||||
"wrong inheritance type", InheritanceType.TABLE_PER_CLASS, entityClass.getInheritanceType()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"wrong table name", "B", configuredClass.getPrimaryTableName()
|
||||
"wrong table name", "B", entityClass.getPrimaryTableName()
|
||||
);
|
||||
|
||||
assertFalse( iter.hasNext() );
|
||||
|
@ -186,28 +184,28 @@ public class TableNameTest extends BaseUnitTestCase {
|
|||
);
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
ConfiguredClass configuredClass = iter.next();
|
||||
ClassInfo info = configuredClass.getClassInfo();
|
||||
Iterator<EntityClass> iter = hierarchies.iterator().next().iterator();
|
||||
EntityClass entityClass = iter.next();
|
||||
ClassInfo info = entityClass.getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( A.class.getName() ), info.name() );
|
||||
assertTrue( configuredClass.hasOwnTable() );
|
||||
assertTrue( entityClass.hasOwnTable() );
|
||||
Assert.assertEquals(
|
||||
"wrong inheritance type", InheritanceType.JOINED, configuredClass.getInheritanceType()
|
||||
"wrong inheritance type", InheritanceType.JOINED, entityClass.getInheritanceType()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"wrong table name", "FOO", configuredClass.getPrimaryTableName()
|
||||
"wrong table name", "FOO", entityClass.getPrimaryTableName()
|
||||
);
|
||||
|
||||
assertTrue( iter.hasNext() );
|
||||
configuredClass = iter.next();
|
||||
info = configuredClass.getClassInfo();
|
||||
entityClass = iter.next();
|
||||
info = entityClass.getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( B.class.getName() ), info.name() );
|
||||
assertTrue( configuredClass.hasOwnTable() );
|
||||
assertTrue( entityClass.hasOwnTable() );
|
||||
Assert.assertEquals(
|
||||
"wrong inheritance type", InheritanceType.JOINED, configuredClass.getInheritanceType()
|
||||
"wrong inheritance type", InheritanceType.JOINED, entityClass.getInheritanceType()
|
||||
);
|
||||
Assert.assertEquals(
|
||||
"wrong table name", "B", configuredClass.getPrimaryTableName()
|
||||
"wrong table name", "B", entityClass.getPrimaryTableName()
|
||||
);
|
||||
|
||||
assertFalse( iter.hasNext() );
|
||||
|
|
|
@ -42,10 +42,8 @@ import org.junit.Test;
|
|||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.metamodel.binding.InheritanceType;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.entity.EntityClass;
|
||||
import org.hibernate.service.ServiceRegistryBuilder;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
import org.hibernate.service.internal.BasicServiceRegistryImpl;
|
||||
|
@ -82,7 +80,7 @@ public class ConfiguredClassHierarchyBuilderTest extends BaseUnitTestCase {
|
|||
);
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
Iterator<EntityClass> iter = hierarchies.iterator().next().iterator();
|
||||
ClassInfo info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( Foo.class.getName() ), info.name() );
|
||||
assertFalse( iter.hasNext() );
|
||||
|
@ -96,7 +94,7 @@ public class ConfiguredClassHierarchyBuilderTest extends BaseUnitTestCase {
|
|||
);
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
Iterator<EntityClass> iter = hierarchies.iterator().next().iterator();
|
||||
ClassInfo info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( A.class.getName() ), info.name() );
|
||||
info = iter.next().getClassInfo();
|
||||
|
@ -139,7 +137,7 @@ public class ConfiguredClassHierarchyBuilderTest extends BaseUnitTestCase {
|
|||
);
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
Iterator<EntityClass> iter = hierarchies.iterator().next().iterator();
|
||||
ClassInfo info = iter.next().getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( MappedSuperClass.class.getName() ), info.name() );
|
||||
info = iter.next().getClassInfo();
|
||||
|
|
|
@ -40,6 +40,7 @@ import org.junit.Test;
|
|||
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.entity.EntityClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.MappedAttribute;
|
||||
import org.hibernate.service.ServiceRegistryBuilder;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
@ -76,7 +77,7 @@ public class GenericTypeDiscoveryTest extends BaseUnitTestCase {
|
|||
);
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
Iterator<EntityClass> iter = hierarchies.iterator().next().iterator();
|
||||
ConfiguredClass configuredClass = iter.next();
|
||||
ClassInfo info = configuredClass.getClassInfo();
|
||||
assertEquals( "wrong class", DotName.createSimple( Stuff.class.getName() ), info.name() );
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.annotations.Parameter;
|
|||
import org.hibernate.annotations.Type;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.entity.EntityClass;
|
||||
import org.hibernate.metamodel.source.annotations.entity.MappedAttribute;
|
||||
import org.hibernate.service.ServiceRegistryBuilder;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
@ -71,7 +72,7 @@ public class TypeDiscoveryTest extends BaseUnitTestCase {
|
|||
);
|
||||
assertEquals( "There should be only one hierarchy", 1, hierarchies.size() );
|
||||
|
||||
Iterator<ConfiguredClass> iter = hierarchies.iterator().next().iterator();
|
||||
Iterator<EntityClass> iter = hierarchies.iterator().next().iterator();
|
||||
ConfiguredClass configuredClass = iter.next();
|
||||
|
||||
MappedAttribute property = configuredClass.getMappedProperty( "id" );
|
||||
|
|
Loading…
Reference in New Issue