HHH-6202 Starting to process the discriminator column

This commit is contained in:
Hardy Ferentschik 2011-05-13 18:39:02 +02:00
parent ab1dca7e86
commit 3bef552483
6 changed files with 220 additions and 79 deletions

View File

@ -33,7 +33,7 @@ import org.hibernate.AssertionFailure;
*
* @author Hardy Ferentschik
*/
public final class ColumnValues {
public class ColumnValues {
private String name = "";
private boolean unique = false;
private boolean nullable = true;
@ -45,14 +45,18 @@ public final class ColumnValues {
private int precision = 0;
private int scale = 0;
public ColumnValues(AnnotationInstance columnAnnotation, boolean isId) {
public ColumnValues() {
this( null );
}
public ColumnValues(AnnotationInstance columnAnnotation) {
if ( columnAnnotation != null && !JPADotNames.COLUMN.equals( columnAnnotation.name() ) ) {
throw new AssertionFailure( "A @Column annotation needs to be passed to the constructor" );
}
applyColumnValues( columnAnnotation, isId );
applyColumnValues( columnAnnotation );
}
private void applyColumnValues(AnnotationInstance columnAnnotation, boolean isId) {
private void applyColumnValues(AnnotationInstance columnAnnotation) {
if ( columnAnnotation == null ) {
return;
}
@ -62,26 +66,14 @@ public final class ColumnValues {
this.name = nameValue.asString();
}
// id attribute must be unique
if ( isId ) {
this.unique = true;
}
else {
AnnotationValue uniqueValue = columnAnnotation.value( "unique" );
if ( uniqueValue != null ) {
this.unique = nameValue.asBoolean();
}
AnnotationValue uniqueValue = columnAnnotation.value( "unique" );
if ( uniqueValue != null ) {
this.unique = nameValue.asBoolean();
}
// id attribute cannot be nullable
if ( isId ) {
this.nullable = false;
}
else {
AnnotationValue nullableValue = columnAnnotation.value( "nullable" );
if ( nullableValue != null ) {
this.nullable = nullableValue.asBoolean();
}
AnnotationValue nullableValue = columnAnnotation.value( "nullable" );
if ( nullableValue != null ) {
this.nullable = nullableValue.asBoolean();
}
AnnotationValue insertableValue = columnAnnotation.value( "insertable" );
@ -160,6 +152,46 @@ public final class ColumnValues {
return scale;
}
public void setName(String name) {
this.name = name;
}
public void setUnique(boolean unique) {
this.unique = unique;
}
public void setNullable(boolean nullable) {
this.nullable = nullable;
}
public void setInsertable(boolean insertable) {
this.insertable = insertable;
}
public void setUpdatable(boolean updatable) {
this.updatable = updatable;
}
public void setColumnDefinition(String columnDefinition) {
this.columnDefinition = columnDefinition;
}
public void setTable(String table) {
this.table = table;
}
public void setLength(int length) {
this.length = length;
}
public void setPrecision(int precision) {
this.precision = precision;
}
public void setScale(int scale) {
this.scale = scale;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();

View File

@ -48,8 +48,10 @@ import org.jboss.jandex.DotName;
import org.jboss.jandex.FieldInfo;
import org.jboss.jandex.MethodInfo;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
import org.hibernate.service.ServiceRegistry;
@ -76,7 +78,8 @@ public class ConfiguredClass {
private final boolean hasOwnTable;
private final String primaryTableName;
private final ConfiguredClassType type;
private final ConfiguredClassType configuredClassType;
private final IdType idType;
private final Map<String, MappedAttribute> mappedAttributes;
@ -93,8 +96,9 @@ public class ConfiguredClass {
this.inheritanceType = inheritanceType;
this.clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( info.toString() );
this.type = determineType();
this.configuredClassType = determineType();
this.classAccessType = determineClassAccessType();
this.idType = determineIdType();
this.hasOwnTable = definesItsOwnTable();
this.primaryTableName = determinePrimaryTableName();
@ -125,14 +129,18 @@ public class ConfiguredClass {
return isRoot;
}
public ConfiguredClassType getType() {
return type;
public ConfiguredClassType getConfiguredClassType() {
return configuredClassType;
}
public InheritanceType getInheritanceType() {
return inheritanceType;
}
public IdType getIdType() {
return idType;
}
public boolean hasOwnTable() {
return hasOwnTable;
}
@ -154,7 +162,7 @@ public class ConfiguredClass {
final StringBuilder sb = new StringBuilder();
sb.append( "ConfiguredClass" );
sb.append( "{clazz=" ).append( clazz.getSimpleName() );
sb.append( ", type=" ).append( type );
sb.append( ", type=" ).append( configuredClassType );
sb.append( ", classAccessType=" ).append( classAccessType );
sb.append( ", isRoot=" ).append( isRoot );
sb.append( ", inheritanceType=" ).append( inheritanceType );
@ -405,8 +413,8 @@ public class ConfiguredClass {
private boolean definesItsOwnTable() {
// mapped super classes and embeddables don't have their own tables
if ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( getType() ) || ConfiguredClassType.EMBEDDABLE
.equals( getType() ) ) {
if ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( getConfiguredClassType() ) || ConfiguredClassType.EMBEDDABLE
.equals( getConfiguredClassType() ) ) {
return false;
}
@ -437,12 +445,44 @@ public class ConfiguredClass {
}
}
else if ( parent != null
&& !parent.getType().equals( ConfiguredClassType.MAPPED_SUPERCLASS )
&& !parent.getType().equals( ConfiguredClassType.EMBEDDABLE ) ) {
&& !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;
}
}

View File

@ -0,0 +1,48 @@
/*
* 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;
/**
* Container for the properties of a discriminator column.
*
* @author Hardy Ferentschik
*/
public class DiscriminatorColumnValues extends ColumnValues {
private static final String DEFAULT_DISCRIMINATOR_COLUMN_NAME = "DTYPE";
private static final String DEFAULT_DISCRIMINATOR_TYPE = "string";
private static final int DEFAULT_DISCRIMINATOR_LENGTH = 31;
public DiscriminatorColumnValues() {
super();
setName( DEFAULT_DISCRIMINATOR_COLUMN_NAME );
setLength( DEFAULT_DISCRIMINATOR_LENGTH );
setNullable( false );
// if ( columnAnnotation != null && !JPADotNames.COLUMN.equals( columnAnnotation.name() ) ) {
// throw new AssertionFailure( "A @Column annotation needs to be passed to the constructor" );
// }
// applyColumnValues( columnAnnotation, isId );
}
}

View File

@ -23,14 +23,11 @@
*/
package org.hibernate.metamodel.source.annotations;
import java.util.List;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import org.hibernate.annotations.OptimisticLockType;
import org.hibernate.annotations.PolymorphismType;
@ -71,6 +68,7 @@ public class EntityBinder {
public void bind() {
EntityBinding entityBinding = new EntityBinding();
entityBinding.setInheritanceType( InheritanceType.get( configuredClass.getInheritanceType() ) );
bindInheritance( entityBinding );
bindJpaEntityAnnotation( entityBinding );
bindHibernateEntityAnnotation( entityBinding ); // optional hibernate specific @org.hibernate.annotations.Entity
@ -91,6 +89,27 @@ public class EntityBinder {
meta.addEntity( entityBinding );
}
private void bindInheritance(EntityBinding entityBinding) {
switch ( configuredClass.getInheritanceType() ) {
case SINGLE_TABLE: {
bindDiscriminatorColumn( entityBinding );
}
case JOINED: {
// todo
}
case TABLE_PER_CLASS: {
// todo
}
default: {
throw new AnnotationException( "Invalid inheritance type " + configuredClass.getInheritanceType() );
}
}
}
private void bindDiscriminatorColumn(EntityBinding entityBinding) {
}
private void bindWhereFilter(EntityBinding entityBinding) {
AnnotationInstance whereAnnotation = JandexHelper.getSingleAnnotation(
configuredClass.getClassInfo(), HibernateDotNames.WHERE
@ -222,7 +241,7 @@ public class EntityBinder {
}
private void bindId(EntityBinding entityBinding) {
switch ( determineIdType() ) {
switch ( configuredClass.getIdType() ) {
case SIMPLE: {
bindSingleIdAnnotation( entityBinding );
break;
@ -383,49 +402,6 @@ public class EntityBinder {
return parentBinding.getEntity();
}
private IdType determineIdType() {
List<AnnotationInstance> idAnnotations = configuredClass.getClassInfo().annotations().get( JPADotNames.ENTITY );
List<AnnotationInstance> embeddedIdAnnotations = configuredClass.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 " + configuredClass.getName() + "."
);
}
if ( embeddedIdAnnotations != null ) {
if ( embeddedIdAnnotations.size() == 1 ) {
return IdType.EMBEDDED;
}
else {
throw new MappingException( "Multiple @EmbeddedId annotations are not allowed" );
}
}
if ( idAnnotations != null ) {
if ( idAnnotations.size() == 1 ) {
return IdType.SIMPLE;
}
else {
return IdType.COMPOSED;
}
}
return IdType.NONE;
}
enum IdType {
// single @Id annotation
SIMPLE,
// multiple @Id annotations
COMPOSED,
// @EmbeddedId annotation
EMBEDDED,
// does not contain any identifier mappings
NONE
}
}

View File

@ -0,0 +1,40 @@
/*
* 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;
/**
* An emum for the type of id configuration for an entity.
*
* @author Hardy Ferentschik
*/
public enum IdType {
// single @Id annotation
SIMPLE,
// multiple @Id annotations
COMPOSED,
// @EmbeddedId annotation
EMBEDDED,
// does not contain any identifier mappings
NONE
}

View File

@ -60,7 +60,12 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
throw new AssertionFailure( "There can only be one @Column annotation per mapped attribute" );
}
AnnotationInstance columnAnnotation = columnAnnotations == null ? null : columnAnnotations.get( 0 );
columnValues = new ColumnValues( columnAnnotation, isId );
columnValues = new ColumnValues( columnAnnotation );
if ( isId ) {
// an id must be unique and cannot be nullable
columnValues.setUnique( true );
columnValues.setNullable( false );
}
}
public final String getName() {