HHH-6202 Binding discriminator column.
Using org.hibernate.metamodel.binding.InheritanceType in ConfiguredClass which has a NO_INHERITANCE enum value. Adding some initial tests
This commit is contained in:
parent
85b0725c28
commit
cb7eb17caa
|
@ -35,7 +35,8 @@ import org.hibernate.MappingException;
|
||||||
public enum InheritanceType {
|
public enum InheritanceType {
|
||||||
JOINED,
|
JOINED,
|
||||||
SINGLE_TABLE,
|
SINGLE_TABLE,
|
||||||
TABLE_PER_CLASS;
|
TABLE_PER_CLASS,
|
||||||
|
NO_INHERITANCE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param jpaType The JPA inheritance type
|
* @param jpaType The JPA inheritance type
|
||||||
|
|
|
@ -35,7 +35,6 @@ import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.persistence.AccessType;
|
import javax.persistence.AccessType;
|
||||||
import javax.persistence.InheritanceType;
|
|
||||||
|
|
||||||
import com.fasterxml.classmate.ResolvedTypeWithMembers;
|
import com.fasterxml.classmate.ResolvedTypeWithMembers;
|
||||||
import com.fasterxml.classmate.members.HierarchicType;
|
import com.fasterxml.classmate.members.HierarchicType;
|
||||||
|
@ -52,6 +51,7 @@ import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.metamodel.binding.InheritanceType;
|
||||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||||
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
@ -117,6 +117,10 @@ public class ConfiguredClass {
|
||||||
return clazz.getName();
|
return clazz.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getSimpleName() {
|
||||||
|
return clazz.getSimpleName();
|
||||||
|
}
|
||||||
|
|
||||||
public ClassInfo getClassInfo() {
|
public ClassInfo getClassInfo() {
|
||||||
return classInfo;
|
return classInfo;
|
||||||
}
|
}
|
||||||
|
@ -375,7 +379,7 @@ public class ConfiguredClass {
|
||||||
final Map<DotName, List<AnnotationInstance>> annotations = JandexHelper.getMemberAnnotations(
|
final Map<DotName, List<AnnotationInstance>> annotations = JandexHelper.getMemberAnnotations(
|
||||||
classInfo, member.getName()
|
classInfo, member.getName()
|
||||||
);
|
);
|
||||||
return new MappedAttribute( name, (Class) type, annotations );
|
return MappedAttribute.createMappedAttribute( name, (Class) type, annotations );
|
||||||
}
|
}
|
||||||
|
|
||||||
private Type findResolvedType(String name, ResolvedMember[] resolvedMembers) {
|
private Type findResolvedType(String name, ResolvedMember[] resolvedMembers) {
|
||||||
|
|
|
@ -27,7 +27,6 @@ import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.persistence.AccessType;
|
import javax.persistence.AccessType;
|
||||||
import javax.persistence.InheritanceType;
|
|
||||||
|
|
||||||
import com.fasterxml.classmate.ResolvedTypeWithMembers;
|
import com.fasterxml.classmate.ResolvedTypeWithMembers;
|
||||||
import org.jboss.jandex.AnnotationInstance;
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
@ -36,6 +35,7 @@ import org.jboss.jandex.FieldInfo;
|
||||||
import org.jboss.jandex.MethodInfo;
|
import org.jboss.jandex.MethodInfo;
|
||||||
|
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
|
import org.hibernate.metamodel.binding.InheritanceType;
|
||||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||||
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
||||||
import org.hibernate.service.ServiceRegistry;
|
import org.hibernate.service.ServiceRegistry;
|
||||||
|
@ -150,6 +150,10 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private InheritanceType determineInheritanceType(List<ClassInfo> classes) {
|
private InheritanceType determineInheritanceType(List<ClassInfo> classes) {
|
||||||
|
if ( classes.size() == 1 ) {
|
||||||
|
return InheritanceType.NO_INHERITANCE;
|
||||||
|
}
|
||||||
|
|
||||||
InheritanceType inheritanceType = null;
|
InheritanceType inheritanceType = null;
|
||||||
for ( ClassInfo info : classes ) {
|
for ( ClassInfo info : classes ) {
|
||||||
AnnotationInstance inheritanceAnnotation = JandexHelper.getSingleAnnotation(
|
AnnotationInstance inheritanceAnnotation = JandexHelper.getSingleAnnotation(
|
||||||
|
@ -159,9 +163,10 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
InheritanceType tmpInheritanceType = Enum.valueOf(
|
javax.persistence.InheritanceType jpaInheritanceType = Enum.valueOf(
|
||||||
InheritanceType.class, inheritanceAnnotation.value( "strategy" ).asEnum()
|
javax.persistence.InheritanceType.class, inheritanceAnnotation.value( "strategy" ).asEnum()
|
||||||
);
|
);
|
||||||
|
InheritanceType tmpInheritanceType = InheritanceType.get( jpaInheritanceType );
|
||||||
if ( tmpInheritanceType == null ) {
|
if ( tmpInheritanceType == null ) {
|
||||||
// default inheritance type is single table
|
// default inheritance type is single table
|
||||||
inheritanceType = InheritanceType.SINGLE_TABLE;
|
inheritanceType = InheritanceType.SINGLE_TABLE;
|
||||||
|
|
|
@ -23,25 +23,90 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.annotations;
|
package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
|
import org.jboss.jandex.DotName;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Container for the properties of a discriminator column.
|
* Container for the properties of a discriminator column.
|
||||||
*
|
*
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
public class DiscriminatorColumnValues extends ColumnValues {
|
public class DiscriminatorColumnValues extends ColumnValues {
|
||||||
private static final String DEFAULT_DISCRIMINATOR_COLUMN_NAME = "DTYPE";
|
public static final String DEFAULT_DISCRIMINATOR_COLUMN_NAME = "DTYPE";
|
||||||
private static final String DEFAULT_DISCRIMINATOR_TYPE = "string";
|
|
||||||
private static final int DEFAULT_DISCRIMINATOR_LENGTH = 31;
|
private static final int DEFAULT_DISCRIMINATOR_LENGTH = 31;
|
||||||
|
|
||||||
public DiscriminatorColumnValues() {
|
private boolean isForced = true;
|
||||||
|
private boolean isIncludedInSql = true;
|
||||||
|
private String discriminatorValue = null;
|
||||||
|
|
||||||
|
public DiscriminatorColumnValues(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||||
super();
|
super();
|
||||||
setName( DEFAULT_DISCRIMINATOR_COLUMN_NAME );
|
|
||||||
setLength( DEFAULT_DISCRIMINATOR_LENGTH );
|
AnnotationInstance discriminatorOptionsAnnotation = JandexHelper.getSingleAnnotation(
|
||||||
|
annotations, JPADotNames.DISCRIMINATOR_COLUMN
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( discriminatorOptionsAnnotation != null ) {
|
||||||
|
setName( discriminatorOptionsAnnotation.value( "name" ).asString() );
|
||||||
|
setLength( discriminatorOptionsAnnotation.value( "length" ).asInt() );
|
||||||
|
if ( discriminatorOptionsAnnotation.value( "columnDefinition" ) != null ) {
|
||||||
|
setColumnDefinition( discriminatorOptionsAnnotation.value( "columnDefinition" ).asString() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
setName( DEFAULT_DISCRIMINATOR_COLUMN_NAME );
|
||||||
|
setLength( DEFAULT_DISCRIMINATOR_LENGTH );
|
||||||
|
}
|
||||||
|
|
||||||
setNullable( false );
|
setNullable( false );
|
||||||
// if ( columnAnnotation != null && !JPADotNames.COLUMN.equals( columnAnnotation.name() ) ) {
|
setDiscriminatorValue( annotations );
|
||||||
// throw new AssertionFailure( "A @Column annotation needs to be passed to the constructor" );
|
setDiscriminatorOptions( annotations );
|
||||||
// }
|
setDiscriminatorFormula( annotations );
|
||||||
// applyColumnValues( columnAnnotation, isId );
|
}
|
||||||
|
|
||||||
|
private void setDiscriminatorValue(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||||
|
AnnotationInstance discriminatorValueAnnotation = JandexHelper.getSingleAnnotation(
|
||||||
|
annotations, JPADotNames.DISCRIMINATOR_VALUE
|
||||||
|
);
|
||||||
|
if ( discriminatorValueAnnotation != null ) {
|
||||||
|
discriminatorValue = discriminatorValueAnnotation.value().asString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDiscriminatorFormula(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||||
|
AnnotationInstance discriminatorFormulaAnnotation = JandexHelper.getSingleAnnotation(
|
||||||
|
annotations, HibernateDotNames.DISCRIMINATOR_FORMULA
|
||||||
|
);
|
||||||
|
if ( discriminatorFormulaAnnotation != null ) {
|
||||||
|
// todo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForced() {
|
||||||
|
return isForced;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isIncludedInSql() {
|
||||||
|
return isIncludedInSql;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDiscriminatorValue() {
|
||||||
|
return discriminatorValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setDiscriminatorOptions(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||||
|
AnnotationInstance discriminatorOptionsAnnotation = JandexHelper.getSingleAnnotation(
|
||||||
|
annotations, HibernateDotNames.DISCRIMINATOR_OPTIONS
|
||||||
|
);
|
||||||
|
if ( discriminatorOptionsAnnotation != null ) {
|
||||||
|
isForced = discriminatorOptionsAnnotation.value( "force" ).asBoolean();
|
||||||
|
isIncludedInSql = discriminatorOptionsAnnotation.value( "insert" ).asBoolean();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ import org.hibernate.cache.spi.access.AccessType;
|
||||||
import org.hibernate.internal.util.StringHelper;
|
import org.hibernate.internal.util.StringHelper;
|
||||||
import org.hibernate.metamodel.binding.Caching;
|
import org.hibernate.metamodel.binding.Caching;
|
||||||
import org.hibernate.metamodel.binding.EntityBinding;
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
import org.hibernate.metamodel.binding.InheritanceType;
|
|
||||||
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||||
import org.hibernate.metamodel.domain.Entity;
|
import org.hibernate.metamodel.domain.Entity;
|
||||||
import org.hibernate.metamodel.domain.Hierarchical;
|
import org.hibernate.metamodel.domain.Hierarchical;
|
||||||
|
@ -67,20 +66,21 @@ public class EntityBinder {
|
||||||
|
|
||||||
public void bind() {
|
public void bind() {
|
||||||
EntityBinding entityBinding = new EntityBinding();
|
EntityBinding entityBinding = new EntityBinding();
|
||||||
entityBinding.setInheritanceType( InheritanceType.get( configuredClass.getInheritanceType() ) );
|
|
||||||
bindInheritance( entityBinding );
|
|
||||||
|
|
||||||
bindJpaEntityAnnotation( entityBinding );
|
bindJpaEntityAnnotation( entityBinding );
|
||||||
bindHibernateEntityAnnotation( entityBinding ); // optional hibernate specific @org.hibernate.annotations.Entity
|
bindHibernateEntityAnnotation( entityBinding ); // optional hibernate specific @org.hibernate.annotations.Entity
|
||||||
|
|
||||||
|
schemaName = createSchemaName();
|
||||||
|
bindTable( entityBinding );
|
||||||
|
|
||||||
|
entityBinding.setInheritanceType( configuredClass.getInheritanceType() );
|
||||||
|
bindInheritance( entityBinding );
|
||||||
|
|
||||||
bindWhereFilter( entityBinding );
|
bindWhereFilter( entityBinding );
|
||||||
|
|
||||||
bindJpaCaching( entityBinding );
|
bindJpaCaching( entityBinding );
|
||||||
bindHibernateCaching( entityBinding );
|
bindHibernateCaching( entityBinding );
|
||||||
|
|
||||||
schemaName = createSchemaName();
|
|
||||||
bindTable( entityBinding );
|
|
||||||
|
|
||||||
if ( configuredClass.isRoot() ) {
|
if ( configuredClass.isRoot() ) {
|
||||||
bindId( entityBinding );
|
bindId( entityBinding );
|
||||||
}
|
}
|
||||||
|
@ -93,21 +93,36 @@ public class EntityBinder {
|
||||||
switch ( configuredClass.getInheritanceType() ) {
|
switch ( configuredClass.getInheritanceType() ) {
|
||||||
case SINGLE_TABLE: {
|
case SINGLE_TABLE: {
|
||||||
bindDiscriminatorColumn( entityBinding );
|
bindDiscriminatorColumn( entityBinding );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case JOINED: {
|
case JOINED: {
|
||||||
// todo
|
// todo
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
case TABLE_PER_CLASS: {
|
case TABLE_PER_CLASS: {
|
||||||
// todo
|
// todo
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
throw new AnnotationException( "Invalid inheritance type " + configuredClass.getInheritanceType() );
|
// do nothing
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindDiscriminatorColumn(EntityBinding entityBinding) {
|
private void bindDiscriminatorColumn(EntityBinding entityBinding) {
|
||||||
|
MappedAttribute discriminatorAttribute = MappedAttribute.createDiscriminatorAttribute(
|
||||||
|
configuredClass.getClassInfo().annotations()
|
||||||
|
);
|
||||||
|
|
||||||
|
bindSingleMappedAttribute( entityBinding, discriminatorAttribute );
|
||||||
|
|
||||||
|
if ( !( discriminatorAttribute.getColumnValues() instanceof DiscriminatorColumnValues ) ) {
|
||||||
|
throw new AssertionFailure( "Expected discriminator column values" );
|
||||||
|
}
|
||||||
|
DiscriminatorColumnValues discriminatorColumnvalues = (DiscriminatorColumnValues) discriminatorAttribute.getColumnValues();
|
||||||
|
entityBinding.getEntityDiscriminator().setForced( discriminatorColumnvalues.isForced() );
|
||||||
|
entityBinding.getEntityDiscriminator().setInserted( discriminatorColumnvalues.isIncludedInSql() );
|
||||||
|
entityBinding.setDiscriminatorValue( discriminatorColumnvalues.getDiscriminatorValue() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindWhereFilter(EntityBinding entityBinding) {
|
private void bindWhereFilter(EntityBinding entityBinding) {
|
||||||
|
@ -295,24 +310,33 @@ public class EntityBinder {
|
||||||
|
|
||||||
private void bindAttributes(EntityBinding entityBinding) {
|
private void bindAttributes(EntityBinding entityBinding) {
|
||||||
for ( MappedAttribute mappedAttribute : configuredClass.getMappedAttributes() ) {
|
for ( MappedAttribute mappedAttribute : configuredClass.getMappedAttributes() ) {
|
||||||
if ( mappedAttribute.isId() ) {
|
bindSingleMappedAttribute( entityBinding, mappedAttribute );
|
||||||
continue;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String attributeName = mappedAttribute.getName();
|
private void bindSingleMappedAttribute(EntityBinding entityBinding, MappedAttribute mappedAttribute) {
|
||||||
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
|
if ( mappedAttribute.isId() ) {
|
||||||
SimpleAttributeBinding attributeBinding;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ( mappedAttribute.isVersioned() ) {
|
String attributeName = mappedAttribute.getName();
|
||||||
attributeBinding = entityBinding.makeVersionBinding( attributeName );
|
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
|
||||||
}
|
SimpleAttributeBinding attributeBinding;
|
||||||
else {
|
|
||||||
attributeBinding = entityBinding.makeSimpleAttributeBinding( attributeName );
|
|
||||||
}
|
|
||||||
|
|
||||||
AttributeDomainState domainState = new AttributeDomainState( entityBinding, mappedAttribute );
|
if ( mappedAttribute.isVersioned() ) {
|
||||||
attributeBinding.initialize( domainState );
|
attributeBinding = entityBinding.makeVersionBinding( attributeName );
|
||||||
|
}
|
||||||
|
else if ( mappedAttribute.isDiscriminator() ) {
|
||||||
|
attributeBinding = entityBinding.makeEntityDiscriminatorBinding( attributeName );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
attributeBinding = entityBinding.makeSimpleAttributeBinding( attributeName );
|
||||||
|
}
|
||||||
|
|
||||||
|
AttributeDomainState domainState = new AttributeDomainState( entityBinding, mappedAttribute );
|
||||||
|
attributeBinding.initialize( domainState );
|
||||||
|
|
||||||
|
if ( configuredClass.hasOwnTable() ) {
|
||||||
AttributeColumnRelationalState columnRelationsState = new AttributeColumnRelationalState(
|
AttributeColumnRelationalState columnRelationsState = new AttributeColumnRelationalState(
|
||||||
mappedAttribute, meta
|
mappedAttribute, meta
|
||||||
);
|
);
|
||||||
|
@ -393,10 +417,10 @@ public class EntityBinder {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityBinding parentBinding = meta.getEntityBinding( parent.getName() );
|
EntityBinding parentBinding = meta.getEntityBinding( parent.getSimpleName() );
|
||||||
if ( parentBinding == null ) {
|
if ( parentBinding == null ) {
|
||||||
throw new AssertionFailure(
|
throw new AssertionFailure(
|
||||||
"Parent entity " + parent.getName() + " of entity " + configuredClass.getName() + "not yet created!"
|
"Parent entity " + parent.getName() + " of entity " + configuredClass.getName() + " not yet created!"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -404,5 +428,3 @@ public class EntityBinder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,14 +25,19 @@ package org.hibernate.metamodel.source.annotations;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.persistence.DiscriminatorType;
|
||||||
|
|
||||||
import org.jboss.jandex.AnnotationInstance;
|
import org.jboss.jandex.AnnotationInstance;
|
||||||
import org.jboss.jandex.DotName;
|
import org.jboss.jandex.DotName;
|
||||||
|
|
||||||
|
import org.hibernate.AnnotationException;
|
||||||
import org.hibernate.AssertionFailure;
|
import org.hibernate.AssertionFailure;
|
||||||
|
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represent a mapped attribute (explicitly or implicitly mapped).
|
* Represent a mapped attribute (explicitly or implicitly mapped). Also used for synthetic attributes likes a
|
||||||
|
* discriminator column.
|
||||||
*
|
*
|
||||||
* @author Hardy Ferentschik
|
* @author Hardy Ferentschik
|
||||||
*/
|
*/
|
||||||
|
@ -43,24 +48,73 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
|
||||||
private final ColumnValues columnValues;
|
private final ColumnValues columnValues;
|
||||||
private final boolean isId;
|
private final boolean isId;
|
||||||
private final boolean isVersioned;
|
private final boolean isVersioned;
|
||||||
|
private final boolean isDiscriminator;
|
||||||
|
|
||||||
MappedAttribute(String name, Class<?> type, Map<DotName, List<AnnotationInstance>> annotations) {
|
static MappedAttribute createMappedAttribute(String name, Class<?> type, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||||
|
return new MappedAttribute( name, type, annotations, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
static MappedAttribute createDiscriminatorAttribute(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||||
|
Map<DotName, List<AnnotationInstance>> discriminatorAnnotations = JandexHelper.filterAnnotations(
|
||||||
|
annotations,
|
||||||
|
JPADotNames.DISCRIMINATOR_COLUMN,
|
||||||
|
JPADotNames.DISCRIMINATOR_VALUE,
|
||||||
|
HibernateDotNames.DISCRIMINATOR_FORMULA,
|
||||||
|
HibernateDotNames.DISCRIMINATOR_OPTIONS
|
||||||
|
);
|
||||||
|
|
||||||
|
AnnotationInstance discriminatorOptionsAnnotation = JandexHelper.getSingleAnnotation(
|
||||||
|
annotations, JPADotNames.DISCRIMINATOR_COLUMN
|
||||||
|
);
|
||||||
|
String name = DiscriminatorColumnValues.DEFAULT_DISCRIMINATOR_COLUMN_NAME;
|
||||||
|
Class<?> type = String.class; // string is the discriminator default
|
||||||
|
if ( discriminatorOptionsAnnotation != null ) {
|
||||||
|
name = discriminatorOptionsAnnotation.value( "name" ).asString();
|
||||||
|
|
||||||
|
DiscriminatorType discriminatorType = Enum.valueOf(
|
||||||
|
DiscriminatorType.class, discriminatorOptionsAnnotation.value( "discriminatorType" ).asEnum()
|
||||||
|
);
|
||||||
|
switch ( discriminatorType ) {
|
||||||
|
case STRING: {
|
||||||
|
type = String.class;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CHAR: {
|
||||||
|
type = Character.class;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case INTEGER: {
|
||||||
|
type = Integer.class;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw new AnnotationException( "Unsupported discriminator type: " + discriminatorType );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new MappedAttribute( name, type, discriminatorAnnotations, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
private MappedAttribute(String name, Class<?> type, Map<DotName, List<AnnotationInstance>> annotations, boolean isDiscriminator) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.annotations = annotations;
|
this.annotations = annotations;
|
||||||
|
this.isDiscriminator = isDiscriminator;
|
||||||
|
|
||||||
List<AnnotationInstance> idAnnotations = annotations.get( JPADotNames.ID );
|
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ID );
|
||||||
isId = idAnnotations != null && !idAnnotations.isEmpty();
|
isId = idAnnotation != null;
|
||||||
|
|
||||||
List<AnnotationInstance> versionAnnotations = annotations.get( JPADotNames.VERSION );
|
AnnotationInstance versionAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.VERSION );
|
||||||
isVersioned = versionAnnotations != null && !versionAnnotations.isEmpty();
|
isVersioned = versionAnnotation != null;
|
||||||
|
|
||||||
List<AnnotationInstance> columnAnnotations = annotations.get( JPADotNames.COLUMN );
|
if ( isDiscriminator ) {
|
||||||
if ( columnAnnotations != null && columnAnnotations.size() > 1 ) {
|
columnValues = new DiscriminatorColumnValues( annotations );
|
||||||
throw new AssertionFailure( "There can only be one @Column annotation per mapped attribute" );
|
|
||||||
}
|
}
|
||||||
AnnotationInstance columnAnnotation = columnAnnotations == null ? null : columnAnnotations.get( 0 );
|
else {
|
||||||
columnValues = new ColumnValues( columnAnnotation );
|
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.COLUMN );
|
||||||
|
columnValues = new ColumnValues( columnAnnotation );
|
||||||
|
}
|
||||||
|
|
||||||
if ( isId ) {
|
if ( isId ) {
|
||||||
// an id must be unique and cannot be nullable
|
// an id must be unique and cannot be nullable
|
||||||
columnValues.setUnique( true );
|
columnValues.setUnique( true );
|
||||||
|
@ -88,6 +142,10 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
|
||||||
return isVersioned;
|
return isVersioned;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDiscriminator() {
|
||||||
|
return isDiscriminator;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the annotation with the specified name or {@code null}
|
* Returns the annotation with the specified name or {@code null}
|
||||||
*
|
*
|
||||||
|
|
|
@ -480,7 +480,6 @@ PrimitiveArray
|
||||||
hibernateMappingBinder.getHibernateXmlBinder().getMetadata(),
|
hibernateMappingBinder.getHibernateXmlBinder().getMetadata(),
|
||||||
hibernateMappingBinder,
|
hibernateMappingBinder,
|
||||||
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName ),
|
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName ),
|
||||||
entityBinding.getMetaAttributes(),
|
|
||||||
discriminator
|
discriminator
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
@ -83,7 +83,6 @@ public class HbmSimpleAttributeDomainState extends AbstractHbmAttributeDomainSta
|
||||||
MetadataImpl metadata,
|
MetadataImpl metadata,
|
||||||
MappingDefaults defaults,
|
MappingDefaults defaults,
|
||||||
org.hibernate.metamodel.domain.Attribute attribute,
|
org.hibernate.metamodel.domain.Attribute attribute,
|
||||||
Map<String, MetaAttribute> entityMetaAttributes,
|
|
||||||
XMLDiscriminator discriminator) {
|
XMLDiscriminator discriminator) {
|
||||||
super(
|
super(
|
||||||
metadata, defaults, attribute, null, null, null, true
|
metadata, defaults, attribute, null, null, null, true
|
||||||
|
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* 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 javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.MetadataSources;
|
||||||
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
|
import org.hibernate.metamodel.source.internal.MetadataImpl;
|
||||||
|
import org.hibernate.service.ServiceRegistryBuilder;
|
||||||
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
|
|
||||||
|
import static junit.framework.Assert.assertEquals;
|
||||||
|
import static junit.framework.Assert.assertNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
public class InheritanceTypeTest extends BaseUnitTestCase {
|
||||||
|
@Test
|
||||||
|
public void testNoInheritance() {
|
||||||
|
MetadataImpl meta = buildMetadata( SingleEntity.class );
|
||||||
|
EntityBinding entityBinding = getEntityBindingForInnerClass( meta, SingleEntity.class );
|
||||||
|
assertNull( entityBinding.getEntityDiscriminator() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDiscriminatorValue() {
|
||||||
|
MetadataImpl meta = buildMetadata( RootOfSingleTableInheritance.class, SubclassOfSingleTableInheritance.class );
|
||||||
|
EntityBinding entityBinding = meta.getEntityBinding( SubclassOfSingleTableInheritance.class.getSimpleName() );
|
||||||
|
assertEquals( "Wrong discriminator value", "foo", entityBinding.getDiscriminatorValue() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private MetadataImpl buildMetadata(Class<?>... classes) {
|
||||||
|
MetadataSources sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
|
||||||
|
for ( Class clazz : classes ) {
|
||||||
|
sources.addAnnotatedClass( clazz );
|
||||||
|
}
|
||||||
|
return (MetadataImpl) sources.buildMetadata();
|
||||||
|
}
|
||||||
|
|
||||||
|
private EntityBinding getEntityBindingForInnerClass(MetadataImpl meta, Class<?> clazz) {
|
||||||
|
return meta.getEntityBinding( this.getClass().getSimpleName() + "$" + clazz.getSimpleName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
class SingleEntity {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private int id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
class RootOfSingleTableInheritance {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue
|
||||||
|
private int id;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
import javax.persistence.DiscriminatorValue;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Hardy Ferentschik
|
||||||
|
*/
|
||||||
|
@Entity
|
||||||
|
@DiscriminatorValue( "foo" )
|
||||||
|
public class SubclassOfSingleTableInheritance extends RootOfSingleTableInheritance {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
import javax.persistence.Inheritance;
|
||||||
import javax.persistence.InheritanceType;
|
|
||||||
import javax.persistence.Table;
|
import javax.persistence.Table;
|
||||||
|
|
||||||
import org.jboss.jandex.ClassInfo;
|
import org.jboss.jandex.ClassInfo;
|
||||||
|
@ -40,6 +39,7 @@ import org.junit.Assert;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.metamodel.binding.InheritanceType;
|
||||||
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
|
import org.hibernate.metamodel.source.annotations.util.ConfiguredClassHierarchyBuilder;
|
||||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||||
import org.hibernate.service.ServiceRegistryBuilder;
|
import org.hibernate.service.ServiceRegistryBuilder;
|
||||||
|
@ -119,7 +119,7 @@ public class TableNameTest extends BaseUnitTestCase {
|
||||||
@Test
|
@Test
|
||||||
public void testTablePerClassDefaultTableName() {
|
public void testTablePerClassDefaultTableName() {
|
||||||
@Entity
|
@Entity
|
||||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
@Inheritance(strategy = javax.persistence.InheritanceType.TABLE_PER_CLASS)
|
||||||
class A {
|
class A {
|
||||||
@Id
|
@Id
|
||||||
@GeneratedValue
|
@GeneratedValue
|
||||||
|
@ -166,7 +166,7 @@ public class TableNameTest extends BaseUnitTestCase {
|
||||||
@Test
|
@Test
|
||||||
public void testJoinedSubclassDefaultTableName() {
|
public void testJoinedSubclassDefaultTableName() {
|
||||||
@Entity
|
@Entity
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
@Inheritance(strategy = javax.persistence.InheritanceType.JOINED)
|
||||||
@Table(name = "FOO")
|
@Table(name = "FOO")
|
||||||
class A {
|
class A {
|
||||||
@Id
|
@Id
|
||||||
|
|
|
@ -31,7 +31,6 @@ import javax.persistence.Entity;
|
||||||
import javax.persistence.GeneratedValue;
|
import javax.persistence.GeneratedValue;
|
||||||
import javax.persistence.Id;
|
import javax.persistence.Id;
|
||||||
import javax.persistence.Inheritance;
|
import javax.persistence.Inheritance;
|
||||||
import javax.persistence.InheritanceType;
|
|
||||||
import javax.persistence.MappedSuperclass;
|
import javax.persistence.MappedSuperclass;
|
||||||
|
|
||||||
import org.jboss.jandex.ClassInfo;
|
import org.jboss.jandex.ClassInfo;
|
||||||
|
@ -42,6 +41,7 @@ import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.hibernate.AnnotationException;
|
import org.hibernate.AnnotationException;
|
||||||
|
import org.hibernate.metamodel.binding.InheritanceType;
|
||||||
import org.hibernate.metamodel.source.annotations.ConfiguredClass;
|
import org.hibernate.metamodel.source.annotations.ConfiguredClass;
|
||||||
import org.hibernate.metamodel.source.annotations.ConfiguredClassHierarchy;
|
import org.hibernate.metamodel.source.annotations.ConfiguredClassHierarchy;
|
||||||
import org.hibernate.service.ServiceRegistryBuilder;
|
import org.hibernate.service.ServiceRegistryBuilder;
|
||||||
|
@ -265,7 +265,7 @@ public class ConfiguredClassHierarchyBuilderTest extends BaseUnitTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
@Inheritance(strategy = javax.persistence.InheritanceType.JOINED)
|
||||||
class A extends MappedSuperClass {
|
class A extends MappedSuperClass {
|
||||||
@Id
|
@Id
|
||||||
String id;
|
String id;
|
||||||
|
@ -281,20 +281,22 @@ public class ConfiguredClassHierarchyBuilderTest extends BaseUnitTestCase {
|
||||||
);
|
);
|
||||||
assertTrue( hierarchies.size() == 1 );
|
assertTrue( hierarchies.size() == 1 );
|
||||||
ConfiguredClassHierarchy hierarchy = hierarchies.iterator().next();
|
ConfiguredClassHierarchy hierarchy = hierarchies.iterator().next();
|
||||||
assertEquals( "Wrong inheritance type", InheritanceType.JOINED, hierarchy.getInheritanceType() );
|
assertEquals(
|
||||||
|
"Wrong inheritance type", InheritanceType.JOINED, hierarchy.getInheritanceType()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = AnnotationException.class)
|
@Test(expected = AnnotationException.class)
|
||||||
public void testMultipleConflictingInheritanceDefinitions() {
|
public void testMultipleConflictingInheritanceDefinitions() {
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Inheritance(strategy = InheritanceType.JOINED)
|
@Inheritance(strategy = javax.persistence.InheritanceType.JOINED)
|
||||||
class A {
|
class A {
|
||||||
String id;
|
String id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
|
@Inheritance(strategy = javax.persistence.InheritanceType.TABLE_PER_CLASS)
|
||||||
class B extends A {
|
class B extends A {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue