HHH-6172 Creating class hierarchy - MappedAttribute -> SimpleAttribute -> AssociationAttribute

This commit is contained in:
Hardy Ferentschik 2011-05-23 22:58:30 +02:00
parent 7a33446f54
commit 49e75c83ce
11 changed files with 405 additions and 248 deletions

View File

@ -23,18 +23,29 @@
*/ */
package org.hibernate.metamodel.source.annotations.entity; package org.hibernate.metamodel.source.annotations.entity;
import java.util.List;
import java.util.Map;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.DotName;
/** /**
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
public class AssociationAttribute { public class AssociationAttribute extends SimpleAttribute {
private final MappedAttribute mappedAttribute; private final AssociationType associationType;
public AssociationAttribute(MappedAttribute mappedAttribute) { public static AssociationAttribute createAssociationAttribute(String name, String type, AssociationType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
this.mappedAttribute = mappedAttribute; return new AssociationAttribute( name, type, associationType, annotations );
} }
public MappedAttribute getMappedAttribute() { private AssociationAttribute(String name, String type, AssociationType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
return mappedAttribute; super( name, type, annotations, false );
this.associationType = associationType;
}
public AssociationType getAssociationType() {
return associationType;
} }
} }

View File

@ -0,0 +1,35 @@
/*
* 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;
/**
* @author Hardy Ferentschik
*/
public enum AssociationType {
NO_ASSOCIATION,
ONE_TO_ONE,
ONE_TO_MANY,
MANY_TO_ONE,
MANY_TO_MANY
}

View File

@ -104,11 +104,11 @@ public class ConfiguredClass {
this.hasOwnTable = definesItsOwnTable(); this.hasOwnTable = definesItsOwnTable();
this.primaryTableName = determinePrimaryTableName(); this.primaryTableName = determinePrimaryTableName();
List<MappedAttribute> properties = collectMappedProperties( resolvedType ); List<MappedAttribute> simpleProps = collectAttributes( resolvedType );
// make sure the properties are ordered by property name // make sure the properties are ordered by property name
Collections.sort( properties ); Collections.sort( simpleProps );
Map<String, MappedAttribute> tmpMap = new LinkedHashMap<String, MappedAttribute>(); Map<String, MappedAttribute> tmpMap = new LinkedHashMap<String, MappedAttribute>();
for ( MappedAttribute property : properties ) { for ( MappedAttribute property : simpleProps ) {
tmpMap.put( property.getName(), property ); tmpMap.put( property.getName(), property );
} }
this.mappedAttributes = Collections.unmodifiableMap( tmpMap ); this.mappedAttributes = Collections.unmodifiableMap( tmpMap );
@ -118,10 +118,6 @@ 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;
} }
@ -212,9 +208,11 @@ public class ConfiguredClass {
} }
/** /**
* @param resolvedTypes the resolved types for the field/properties of this class
*
* @return A list of the persistent properties of this configured class * @return A list of the persistent properties of this configured class
*/ */
private List<MappedAttribute> collectMappedProperties(ResolvedTypeWithMembers resolvedTypes) { private List<MappedAttribute> collectAttributes(ResolvedTypeWithMembers resolvedTypes) {
// create sets of transient field and method names // create sets of transient field and method names
Set<String> transientFieldNames = new HashSet<String>(); Set<String> transientFieldNames = new HashSet<String>();
Set<String> transientMethodNames = new HashSet<String>(); Set<String> transientMethodNames = new HashSet<String>();
@ -279,6 +277,7 @@ public class ConfiguredClass {
* Creates {@code MappedProperty} instances for the explicitly configured persistent properties * Creates {@code MappedProperty} instances for the explicitly configured persistent properties
* *
* @param mappedProperties list to which to add the explicitly configured mapped properties * @param mappedProperties list to which to add the explicitly configured mapped properties
* @param resolvedMembers the resolved type parameters for this class
* *
* @return the property names of the explicitly configured class names in a set * @return the property names of the explicitly configured class names in a set
*/ */
@ -380,7 +379,48 @@ 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 MappedAttribute.createMappedAttribute( name, ( (Class) type ).getName(), annotations );
MappedAttribute attribute;
AssociationType associationType = determineAssociationType( annotations );
switch ( associationType ) {
case NO_ASSOCIATION: {
attribute = SimpleAttribute.createSimpleAttribute( name, ( (Class) type ).getName(), annotations );
break;
}
default: {
attribute = AssociationAttribute.createAssociationAttribute(
name, ( (Class) type ).getName(), associationType, annotations
);
}
}
return attribute;
}
private AssociationType determineAssociationType(Map<DotName, List<AnnotationInstance>> annotations) {
AnnotationInstance oneToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE );
AnnotationInstance oneToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY );
AnnotationInstance manyToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_ONE );
AnnotationInstance manyToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY );
if ( oneToOne == null && oneToMany == null && manyToOne == null && manyToMany == null ) {
return AssociationType.NO_ASSOCIATION;
}
else if ( oneToOne != null && oneToMany == null && manyToOne == null && manyToMany == null ) {
return AssociationType.ONE_TO_ONE;
}
else if ( oneToOne == null && oneToMany != null && manyToOne == null && manyToMany == null ) {
return AssociationType.ONE_TO_MANY;
}
else if ( oneToOne == null && oneToMany == null && manyToOne != null && manyToMany == null ) {
return AssociationType.MANY_TO_ONE;
}
else if ( oneToOne == null && oneToMany == null && manyToOne == null && manyToMany != null ) {
return AssociationType.MANY_TO_MANY;
}
else {
throw new AnnotationException( "More than one association type configured for property " + getName() + " of class " + getName() );
}
} }
private Type findResolvedType(String name, ResolvedMember[] resolvedMembers) { private Type findResolvedType(String name, ResolvedMember[] resolvedMembers) {

View File

@ -122,7 +122,7 @@ public class EntityBinder {
final Map<DotName, List<AnnotationInstance>> typeAnnotations = JandexHelper.getTypeAnnotations( final Map<DotName, List<AnnotationInstance>> typeAnnotations = JandexHelper.getTypeAnnotations(
configuredClass.getClassInfo() configuredClass.getClassInfo()
); );
MappedAttribute discriminatorAttribute = MappedAttribute.createDiscriminatorAttribute( typeAnnotations ); SimpleAttribute discriminatorAttribute = SimpleAttribute.createDiscriminatorAttribute( typeAnnotations );
bindSingleMappedAttribute( entityBinding, discriminatorAttribute ); bindSingleMappedAttribute( entityBinding, discriminatorAttribute );
@ -305,21 +305,29 @@ public class EntityBinder {
String idName = JandexHelper.getPropertyName( idAnnotation.target() ); String idName = JandexHelper.getPropertyName( idAnnotation.target() );
MappedAttribute idAttribute = configuredClass.getMappedProperty( idName ); MappedAttribute idAttribute = configuredClass.getMappedProperty( idName );
if ( !( idAttribute instanceof SimpleAttribute ) ) {
throw new AssertionFailure( "Unexpected attribute type for id attribute" );
}
entityBinding.getEntity().getOrCreateSingularAttribute( idName ); entityBinding.getEntity().getOrCreateSingularAttribute( idName );
SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( idName ); SimpleAttributeBinding attributeBinding = entityBinding.makeSimpleIdAttributeBinding( idName );
attributeBinding.initialize( new AttributeBindingStateImpl( idAttribute ) ); attributeBinding.initialize( new AttributeBindingStateImpl( (SimpleAttribute) idAttribute ) );
attributeBinding.initialize( new ColumnRelationalStateImpl( idAttribute, meta ) ); attributeBinding.initialize( new ColumnRelationalStateImpl( (SimpleAttribute) idAttribute, meta ) );
} }
private void bindAttributes(EntityBinding entityBinding) { private void bindAttributes(EntityBinding entityBinding) {
for ( MappedAttribute mappedAttribute : configuredClass.getMappedAttributes() ) { for ( MappedAttribute mappedAttribute : configuredClass.getMappedAttributes() ) {
bindSingleMappedAttribute( entityBinding, mappedAttribute ); if ( mappedAttribute instanceof AssociationAttribute ) {
// todo
}
else {
bindSingleMappedAttribute( entityBinding, (SimpleAttribute) mappedAttribute );
}
} }
} }
private void bindSingleMappedAttribute(EntityBinding entityBinding, MappedAttribute mappedAttribute) { private void bindSingleMappedAttribute(EntityBinding entityBinding, SimpleAttribute mappedAttribute) {
if ( mappedAttribute.isId() ) { if ( mappedAttribute.isId() ) {
return; return;
} }

View File

@ -26,24 +26,16 @@ package org.hibernate.metamodel.source.annotations.entity;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.persistence.DiscriminatorType;
import javax.persistence.FetchType;
import org.jboss.jandex.AnnotationInstance; import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue; import org.jboss.jandex.AnnotationValue;
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.annotations.GenerationTime;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.annotations.HibernateDotNames; import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
/** /**
* Represent a mapped attribute (explicitly or implicitly mapped). Also used for synthetic attributes like a * Base class for the different types of mapped attributes
* discriminator column.
* *
* @author Hardy Ferentschik * @author Hardy Ferentschik
*/ */
@ -53,11 +45,6 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
*/ */
private final Map<DotName, List<AnnotationInstance>> annotations; private final Map<DotName, List<AnnotationInstance>> annotations;
/**
* The property name.
*/
private final String name;
/** /**
* The property type as string. * The property type as string.
*/ */
@ -69,117 +56,19 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
private final Map<String, String> typeParameters; private final Map<String, String> typeParameters;
/** /**
* Is this property an id property (or part thereof). * The property name.
*/ */
private final boolean isId; private final String name;
/** MappedAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations) {
* Is this a versioned property (annotated w/ {@code @Version}.
*/
private final boolean isVersioned;
/**
* Is this property a discriminator property.
*/
private final boolean isDiscriminator;
/**
* Whether a change of the property's value triggers a version increment of the entity (in case of optimistic
* locking).
*/
private final boolean isOptimisticLockable;
/**
* Is this property lazy loaded (see {@link javax.persistence.Basic}).
*/
private boolean isLazy = false;
/**
* Is this property optional (see {@link javax.persistence.Basic}).
*/
private boolean isOptional = true;
private PropertyGeneration propertyGeneration;
private boolean isInsertable = true;
private boolean isUpdatable = true;
/**
* Defines the column values (relational values) for this property.
*/
private final ColumnValues columnValues;
static MappedAttribute createMappedAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations) {
return new MappedAttribute( name, type, annotations, false );
}
static MappedAttribute createDiscriminatorAttribute(Map<DotName, List<AnnotationInstance>> annotations) {
AnnotationInstance discriminatorOptionsAnnotation = JandexHelper.getSingleAnnotation(
annotations, JPADotNames.DISCRIMINATOR_COLUMN
);
String name = DiscriminatorColumnValues.DEFAULT_DISCRIMINATOR_COLUMN_NAME;
String type = String.class.toString(); // 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.toString();
break;
}
case CHAR: {
type = Character.class.toString();
break;
}
case INTEGER: {
type = Integer.class.toString();
break;
}
default: {
throw new AnnotationException( "Unsupported discriminator type: " + discriminatorType );
}
}
}
return new MappedAttribute( name, type, annotations, true );
}
private MappedAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations, boolean isDiscriminator) {
this.name = name;
this.annotations = annotations; this.annotations = annotations;
this.isDiscriminator = isDiscriminator; this.name = name;
this.typeParameters = new HashMap<String, String>(); this.typeParameters = new HashMap<String, String>();
this.type = determineType( type, typeParameters ); this.type = determineType( type, typeParameters );
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ID );
isId = idAnnotation != null;
AnnotationInstance versionAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.VERSION );
isVersioned = versionAnnotation != null;
if ( isDiscriminator ) {
columnValues = new DiscriminatorColumnValues( annotations );
}
else {
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.COLUMN );
columnValues = new ColumnValues( columnAnnotation );
}
if ( isId ) {
// an id must be unique and cannot be nullable
columnValues.setUnique( true );
columnValues.setNullable( false );
}
this.isOptimisticLockable = checkOptimisticLockAnnotation();
checkBasicAnnotation();
checkGeneratedAnnotation();
} }
public final String getName() { public String getName() {
return name; return name;
} }
@ -187,50 +76,10 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
return type; return type;
} }
public final ColumnValues getColumnValues() {
return columnValues;
}
public Map<String, String> getTypeParameters() { public Map<String, String> getTypeParameters() {
return typeParameters; return typeParameters;
} }
public boolean isId() {
return isId;
}
public boolean isVersioned() {
return isVersioned;
}
public boolean isDiscriminator() {
return isDiscriminator;
}
public boolean isLazy() {
return isLazy;
}
public boolean isOptional() {
return isOptional;
}
public boolean isInsertable() {
return isInsertable;
}
public boolean isUpdatable() {
return isUpdatable;
}
public PropertyGeneration getPropertyGeneration() {
return propertyGeneration;
}
public boolean isOptimisticLockable() {
return isOptimisticLockable;
}
/** /**
* Returns the annotation with the specified name or {@code null} * Returns the annotation with the specified name or {@code null}
* *
@ -252,24 +101,6 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
} }
} }
@Override
public int compareTo(MappedAttribute mappedProperty) {
return name.compareTo( mappedProperty.getName() );
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "MappedAttribute" );
sb.append( "{name='" ).append( name ).append( '\'' );
sb.append( ", type='" ).append( type ).append( '\'' );
sb.append( ", isId=" ).append( isId );
sb.append( ", isVersioned=" ).append( isVersioned );
sb.append( ", isDiscriminator=" ).append( isDiscriminator );
sb.append( '}' );
return sb.toString();
}
/** /**
* We need to check whether the is an explicit type specified via {@link org.hibernate.annotations.Type}. * We need to check whether the is an explicit type specified via {@link org.hibernate.annotations.Type}.
* *
@ -299,48 +130,20 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
return typeAnnotation.value( "type" ).asString(); return typeAnnotation.value( "type" ).asString();
} }
private boolean checkOptimisticLockAnnotation() { @Override
boolean triggersVersionIncrement = true; public int compareTo(MappedAttribute mappedProperty) {
AnnotationInstance optimisticLockAnnotation = getIfExists( HibernateDotNames.OPTIMISTIC_LOCK ); return name.compareTo( mappedProperty.getName() );
if ( optimisticLockAnnotation != null ) {
boolean exclude = optimisticLockAnnotation.value( "excluded" ).asBoolean();
triggersVersionIncrement = !exclude;
}
return triggersVersionIncrement;
} }
private void checkBasicAnnotation() { @Override
AnnotationInstance basicAnnotation = getIfExists( JPADotNames.BASIC ); public String toString() {
if ( basicAnnotation != null ) { final StringBuilder sb = new StringBuilder();
FetchType fetchType = FetchType.LAZY; sb.append( "MappedAttribute" );
AnnotationValue fetchValue = basicAnnotation.value( "fetch" ); sb.append( "{type='" ).append( type ).append( '\'' );
if ( fetchValue != null ) { sb.append( ", typeParameters=" ).append( typeParameters );
fetchType = Enum.valueOf( FetchType.class, fetchValue.asEnum() ); sb.append( ", name='" ).append( name ).append( '\'' );
} sb.append( '}' );
this.isLazy = fetchType == FetchType.LAZY; return sb.toString();
AnnotationValue optionalValue = basicAnnotation.value( "optional" );
if ( optionalValue != null ) {
this.isOptional = optionalValue.asBoolean();
}
}
}
// TODO - there is more todo for updatable and insertable. Checking the @Generated annotation is only one part (HF)
private void checkGeneratedAnnotation() {
AnnotationInstance generatedAnnotation = getIfExists( HibernateDotNames.GENERATED );
if ( generatedAnnotation != null ) {
this.isInsertable = false;
AnnotationValue generationTimeValue = generatedAnnotation.value();
if ( generationTimeValue != null ) {
GenerationTime genTime = Enum.valueOf( GenerationTime.class, generationTimeValue.asEnum() );
if ( GenerationTime.ALWAYS.equals( genTime ) ) {
this.isUpdatable = false;
this.propertyGeneration = PropertyGeneration.parse( genTime.toString().toLowerCase() );
}
}
}
} }
} }

View File

@ -0,0 +1,261 @@
/*
* 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 java.util.Map;
import javax.persistence.DiscriminatorType;
import javax.persistence.FetchType;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.hibernate.AnnotationException;
import org.hibernate.annotations.GenerationTime;
import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.JPADotNames;
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
/**
* Represent a mapped attribute (explicitly or implicitly mapped). Also used for synthetic attributes like a
* discriminator column.
*
* @author Hardy Ferentschik
*/
public class SimpleAttribute extends MappedAttribute {
/**
* Is this property an id property (or part thereof).
*/
private final boolean isId;
/**
* Is this a versioned property (annotated w/ {@code @Version}.
*/
private final boolean isVersioned;
/**
* Is this property a discriminator property.
*/
private final boolean isDiscriminator;
/**
* Whether a change of the property's value triggers a version increment of the entity (in case of optimistic
* locking).
*/
private final boolean isOptimisticLockable;
/**
* Is this property lazy loaded (see {@link javax.persistence.Basic}).
*/
private boolean isLazy = false;
/**
* Is this property optional (see {@link javax.persistence.Basic}).
*/
private boolean isOptional = true;
private PropertyGeneration propertyGeneration;
private boolean isInsertable = true;
private boolean isUpdatable = true;
/**
* Defines the column values (relational values) for this property.
*/
private final ColumnValues columnValues;
static SimpleAttribute createSimpleAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations) {
return new SimpleAttribute( name, type, annotations, false );
}
static SimpleAttribute createDiscriminatorAttribute(Map<DotName, List<AnnotationInstance>> annotations) {
AnnotationInstance discriminatorOptionsAnnotation = JandexHelper.getSingleAnnotation(
annotations, JPADotNames.DISCRIMINATOR_COLUMN
);
String name = DiscriminatorColumnValues.DEFAULT_DISCRIMINATOR_COLUMN_NAME;
String type = String.class.toString(); // 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.toString();
break;
}
case CHAR: {
type = Character.class.toString();
break;
}
case INTEGER: {
type = Integer.class.toString();
break;
}
default: {
throw new AnnotationException( "Unsupported discriminator type: " + discriminatorType );
}
}
}
return new SimpleAttribute( name, type, annotations, true );
}
SimpleAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations, boolean isDiscriminator) {
super( name, type, annotations );
this.isDiscriminator = isDiscriminator;
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ID );
isId = idAnnotation != null;
AnnotationInstance versionAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.VERSION );
isVersioned = versionAnnotation != null;
if ( isDiscriminator ) {
columnValues = new DiscriminatorColumnValues( annotations );
}
else {
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.COLUMN );
columnValues = new ColumnValues( columnAnnotation );
}
if ( isId ) {
// an id must be unique and cannot be nullable
columnValues.setUnique( true );
columnValues.setNullable( false );
}
this.isOptimisticLockable = checkOptimisticLockAnnotation();
checkBasicAnnotation();
checkGeneratedAnnotation();
}
public final ColumnValues getColumnValues() {
return columnValues;
}
public boolean isId() {
return isId;
}
public boolean isVersioned() {
return isVersioned;
}
public boolean isDiscriminator() {
return isDiscriminator;
}
public boolean isLazy() {
return isLazy;
}
public boolean isOptional() {
return isOptional;
}
public boolean isInsertable() {
return isInsertable;
}
public boolean isUpdatable() {
return isUpdatable;
}
public PropertyGeneration getPropertyGeneration() {
return propertyGeneration;
}
public boolean isOptimisticLockable() {
return isOptimisticLockable;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "SimpleAttribute" );
sb.append( "{isId=" ).append( isId );
sb.append( ", isVersioned=" ).append( isVersioned );
sb.append( ", isDiscriminator=" ).append( isDiscriminator );
sb.append( ", isOptimisticLockable=" ).append( isOptimisticLockable );
sb.append( ", isLazy=" ).append( isLazy );
sb.append( ", isOptional=" ).append( isOptional );
sb.append( ", propertyGeneration=" ).append( propertyGeneration );
sb.append( ", isInsertable=" ).append( isInsertable );
sb.append( ", isUpdatable=" ).append( isUpdatable );
sb.append( '}' );
return sb.toString();
}
private boolean checkOptimisticLockAnnotation() {
boolean triggersVersionIncrement = true;
AnnotationInstance optimisticLockAnnotation = getIfExists( HibernateDotNames.OPTIMISTIC_LOCK );
if ( optimisticLockAnnotation != null ) {
boolean exclude = optimisticLockAnnotation.value( "excluded" ).asBoolean();
triggersVersionIncrement = !exclude;
}
return triggersVersionIncrement;
}
private void checkBasicAnnotation() {
AnnotationInstance basicAnnotation = getIfExists( JPADotNames.BASIC );
if ( basicAnnotation != null ) {
FetchType fetchType = FetchType.LAZY;
AnnotationValue fetchValue = basicAnnotation.value( "fetch" );
if ( fetchValue != null ) {
fetchType = Enum.valueOf( FetchType.class, fetchValue.asEnum() );
}
this.isLazy = fetchType == FetchType.LAZY;
AnnotationValue optionalValue = basicAnnotation.value( "optional" );
if ( optionalValue != null ) {
this.isOptional = optionalValue.asBoolean();
}
}
}
// TODO - there is more todo for updatable and insertable. Checking the @Generated annotation is only one part (HF)
private void checkGeneratedAnnotation() {
AnnotationInstance generatedAnnotation = getIfExists( HibernateDotNames.GENERATED );
if ( generatedAnnotation != null ) {
this.isInsertable = false;
AnnotationValue generationTimeValue = generatedAnnotation.value();
if ( generationTimeValue != null ) {
GenerationTime genTime = Enum.valueOf( GenerationTime.class, generationTimeValue.asEnum() );
if ( GenerationTime.ALWAYS.equals( genTime ) ) {
this.isUpdatable = false;
this.propertyGeneration = PropertyGeneration.parse( genTime.toString().toLowerCase() );
}
}
}
}
}

View File

@ -28,7 +28,7 @@ import java.util.Map;
import org.hibernate.mapping.PropertyGeneration; import org.hibernate.mapping.PropertyGeneration;
import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState; import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState;
import org.hibernate.metamodel.domain.MetaAttribute; import org.hibernate.metamodel.domain.MetaAttribute;
import org.hibernate.metamodel.source.annotations.entity.MappedAttribute; import org.hibernate.metamodel.source.annotations.entity.SimpleAttribute;
/** /**
* Implementation of the attribute binding state via annotation configuration. * Implementation of the attribute binding state via annotation configuration.
@ -37,9 +37,9 @@ import org.hibernate.metamodel.source.annotations.entity.MappedAttribute;
* @todo in the end we can maybe just let MappedAttribute implement SimpleAttributeBindingState. (HF) * @todo in the end we can maybe just let MappedAttribute implement SimpleAttributeBindingState. (HF)
*/ */
public class AttributeBindingStateImpl implements SimpleAttributeBindingState { public class AttributeBindingStateImpl implements SimpleAttributeBindingState {
private final MappedAttribute mappedAttribute; private final SimpleAttribute mappedAttribute;
public AttributeBindingStateImpl(MappedAttribute mappedAttribute) { public AttributeBindingStateImpl(SimpleAttribute mappedAttribute) {
this.mappedAttribute = mappedAttribute; this.mappedAttribute = mappedAttribute;
} }

View File

@ -24,7 +24,7 @@
package org.hibernate.metamodel.source.annotations.entity.state.binding; package org.hibernate.metamodel.source.annotations.entity.state.binding;
import org.hibernate.metamodel.source.annotations.entity.DiscriminatorColumnValues; import org.hibernate.metamodel.source.annotations.entity.DiscriminatorColumnValues;
import org.hibernate.metamodel.source.annotations.entity.MappedAttribute; import org.hibernate.metamodel.source.annotations.entity.SimpleAttribute;
/** /**
* @author Gail Badner * @author Gail Badner
@ -36,7 +36,7 @@ public class DiscriminatorBindingStateImpl
private final boolean isForced; private final boolean isForced;
private final boolean isInserted; private final boolean isInserted;
public DiscriminatorBindingStateImpl(MappedAttribute mappedAttribute) { public DiscriminatorBindingStateImpl(SimpleAttribute mappedAttribute) {
super( mappedAttribute ); super( mappedAttribute );
DiscriminatorColumnValues columnValues = DiscriminatorColumnValues.class.cast( mappedAttribute.getColumnValues() ); DiscriminatorColumnValues columnValues = DiscriminatorColumnValues.class.cast( mappedAttribute.getColumnValues() );
isForced = columnValues.isForced(); isForced = columnValues.isForced();

View File

@ -31,7 +31,7 @@ import org.hibernate.metamodel.source.annotations.entity.AssociationAttribute;
*/ */
public class ManyToOneBindingStateImpl extends AttributeBindingStateImpl implements ManyToOneAttributeBindingState { public class ManyToOneBindingStateImpl extends AttributeBindingStateImpl implements ManyToOneAttributeBindingState {
public ManyToOneBindingStateImpl(AssociationAttribute associationAttribute) { public ManyToOneBindingStateImpl(AssociationAttribute associationAttribute) {
super( associationAttribute.getMappedAttribute() ); super( associationAttribute );
} }
@Override @Override

View File

@ -37,7 +37,7 @@ import org.hibernate.metamodel.relational.Size;
import org.hibernate.metamodel.relational.state.ColumnRelationalState; import org.hibernate.metamodel.relational.state.ColumnRelationalState;
import org.hibernate.metamodel.source.annotations.HibernateDotNames; import org.hibernate.metamodel.source.annotations.HibernateDotNames;
import org.hibernate.metamodel.source.annotations.entity.ColumnValues; import org.hibernate.metamodel.source.annotations.entity.ColumnValues;
import org.hibernate.metamodel.source.annotations.entity.MappedAttribute; import org.hibernate.metamodel.source.annotations.entity.SimpleAttribute;
import org.hibernate.metamodel.source.spi.MetadataImplementor; import org.hibernate.metamodel.source.spi.MetadataImplementor;
/** /**
@ -61,7 +61,7 @@ public class ColumnRelationalStateImpl implements ColumnRelationalState {
private Set<String> uniqueKeys = new HashSet<String>(); private Set<String> uniqueKeys = new HashSet<String>();
public ColumnRelationalStateImpl(MappedAttribute attribute, MetadataImplementor meta) { public ColumnRelationalStateImpl(SimpleAttribute attribute, MetadataImplementor meta) {
ColumnValues columnValues = attribute.getColumnValues(); ColumnValues columnValues = attribute.getColumnValues();
namingStrategy = meta.getOptions().getNamingStrategy(); namingStrategy = meta.getOptions().getNamingStrategy();
columnName = columnValues.getName().isEmpty() ? attribute.getName() : columnValues.getName(); columnName = columnValues.getName().isEmpty() ? attribute.getName() : columnValues.getName();
@ -151,7 +151,7 @@ public class ColumnRelationalStateImpl implements ColumnRelationalState {
return size; return size;
} }
private List<AnnotationInstance> getAllColumnTransformerAnnotations(MappedAttribute attribute) { private List<AnnotationInstance> getAllColumnTransformerAnnotations(SimpleAttribute attribute) {
List<AnnotationInstance> allColumnTransformerAnnotations = new ArrayList<AnnotationInstance>(); List<AnnotationInstance> allColumnTransformerAnnotations = new ArrayList<AnnotationInstance>();
// not quite sure about the usefulness of @ColumnTransformers (HF) // not quite sure about the usefulness of @ColumnTransformers (HF)
@ -194,7 +194,7 @@ public class ColumnRelationalStateImpl implements ColumnRelationalState {
return readWrite; return readWrite;
} }
private String parseCheckAnnotation(MappedAttribute attribute) { private String parseCheckAnnotation(SimpleAttribute attribute) {
String checkCondition = null; String checkCondition = null;
AnnotationInstance checkAnnotation = attribute.getIfExists( HibernateDotNames.CHECK ); AnnotationInstance checkAnnotation = attribute.getIfExists( HibernateDotNames.CHECK );
if ( checkAnnotation != null ) { if ( checkAnnotation != null ) {
@ -203,7 +203,7 @@ public class ColumnRelationalStateImpl implements ColumnRelationalState {
return checkCondition; return checkCondition;
} }
private Set<String> parseIndexAnnotation(MappedAttribute attribute) { private Set<String> parseIndexAnnotation(SimpleAttribute attribute) {
Set<String> indexNames = new HashSet<String>(); Set<String> indexNames = new HashSet<String>();
AnnotationInstance indexAnnotation = attribute.getIfExists( HibernateDotNames.INDEX ); AnnotationInstance indexAnnotation = attribute.getIfExists( HibernateDotNames.INDEX );
if ( indexAnnotation != null ) { if ( indexAnnotation != null ) {

View File

@ -23,11 +23,10 @@
*/ */
package org.hibernate.metamodel.binding; package org.hibernate.metamodel.binding;
import javax.persistence.Entity;
import javax.persistence.Id; import javax.persistence.Id;
import javax.persistence.ManyToOne; import javax.persistence.ManyToOne;
import org.hibernate.annotations.Entity;
/** /**
* @author Gail Badner * @author Gail Badner
*/ */