HHH-6537 Getting AssociationAttribute into shape. Parsing more association attributes and implementing missing attributes in ToOneAttributeSourceImpl.
Preperation for adding @MapsId
This commit is contained in:
parent
683478674c
commit
eb766cc0f7
|
@ -23,18 +23,25 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.source.annotations;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.GenerationType;
|
||||
|
||||
import org.hibernate.AssertionFailure;
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.id.MultipleHiLoPerTableGenerator;
|
||||
import org.hibernate.internal.util.collections.CollectionHelper;
|
||||
|
||||
/**
|
||||
* Helper class which converts type enums from JPA annotations into the Hibernate specific form
|
||||
* Helper class which converts between different enum types.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class TypeEnumConversionHelper {
|
||||
private TypeEnumConversionHelper() {
|
||||
public class EnumConversionHelper {
|
||||
private EnumConversionHelper() {
|
||||
}
|
||||
|
||||
public static String generationTypeToGeneratorStrategyName(GenerationType generatorEnum, boolean useNewGeneratorMappings) {
|
||||
|
@ -56,6 +63,62 @@ public class TypeEnumConversionHelper {
|
|||
}
|
||||
throw new AssertionFailure( "Unknown GeneratorType: " + generatorEnum );
|
||||
}
|
||||
|
||||
public static CascadeStyle cascadeTypeToCascadeStyle(CascadeType cascadeType) {
|
||||
switch ( cascadeType ) {
|
||||
case ALL: {
|
||||
return CascadeStyle.ALL;
|
||||
}
|
||||
case PERSIST: {
|
||||
return CascadeStyle.PERSIST;
|
||||
}
|
||||
case MERGE: {
|
||||
return CascadeStyle.MERGE;
|
||||
}
|
||||
case REMOVE: {
|
||||
return CascadeStyle.DELETE;
|
||||
}
|
||||
case REFRESH: {
|
||||
return CascadeStyle.REFRESH;
|
||||
}
|
||||
case DETACH: {
|
||||
return CascadeStyle.EVICT;
|
||||
}
|
||||
default: {
|
||||
throw new AssertionFailure( "Unknown cascade type" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static FetchMode annotationFetchModeToHibernateFetchMode(org.hibernate.annotations.FetchMode annotationFetchMode) {
|
||||
switch ( annotationFetchMode ) {
|
||||
case JOIN: {
|
||||
return FetchMode.JOIN;
|
||||
}
|
||||
case SELECT: {
|
||||
return FetchMode.SELECT;
|
||||
}
|
||||
case SUBSELECT: {
|
||||
// todo - is this correct? can the conversion be made w/o any additional information, eg
|
||||
// todo - association nature
|
||||
return FetchMode.SELECT;
|
||||
}
|
||||
default: {
|
||||
throw new AssertionFailure( "Unknown fetch mode" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<CascadeStyle> cascadeTypeToCascadeStyleSet(Set<CascadeType> cascadeTypes) {
|
||||
if ( CollectionHelper.isEmpty( cascadeTypes ) ) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
Set<CascadeStyle> cascadeStyleSet = new HashSet<CascadeStyle>();
|
||||
for ( CascadeType cascadeType : cascadeTypes ) {
|
||||
cascadeStyleSet.add( cascadeTypeToCascadeStyle( cascadeType ) );
|
||||
}
|
||||
return cascadeStyleSet;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -55,6 +55,9 @@ import org.hibernate.service.classloading.spi.ClassLoaderService;
|
|||
public class JandexHelper {
|
||||
private static final Map<String, Object> DEFAULT_VALUES_BY_ELEMENT = new HashMap<String, Object>();
|
||||
|
||||
private JandexHelper() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a jandex annotation element value. If the value is {@code null}, the default value specified in the
|
||||
* annotation class is retrieved instead.
|
||||
|
@ -212,6 +215,19 @@ public class JandexHelper {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param annotations List of annotation instances keyed against their dot name.
|
||||
* @param annotationName the annotation to check
|
||||
*
|
||||
* @return returns {@code true} if the map contains only a single instance of specified annotation or {@code false} otherwise.
|
||||
*
|
||||
* @throws org.hibernate.AssertionFailure in case there is there is more than one annotation of this type.
|
||||
*/
|
||||
public static boolean containsSingleAnnotations(Map<DotName, List<AnnotationInstance>> annotations, DotName annotationName)
|
||||
throws AssertionFailure {
|
||||
return getSingleAnnotation( annotations, annotationName ) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a jandex index for the specified classes
|
||||
*
|
||||
|
@ -274,7 +290,7 @@ public class JandexHelper {
|
|||
return annotations;
|
||||
}
|
||||
|
||||
public static void addAnnotationToMap(AnnotationInstance instance, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
private static void addAnnotationToMap(AnnotationInstance instance, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
DotName dotName = instance.name();
|
||||
List<AnnotationInstance> list;
|
||||
if ( annotations.containsKey( dotName ) ) {
|
||||
|
@ -287,9 +303,6 @@ public class JandexHelper {
|
|||
list.add( instance );
|
||||
}
|
||||
|
||||
private JandexHelper() {
|
||||
}
|
||||
|
||||
private static Object getDefaultValue(AnnotationInstance annotation, String element) {
|
||||
String name = annotation.name().toString();
|
||||
String fqElement = name + '.' + element;
|
||||
|
|
|
@ -28,42 +28,67 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import javax.persistence.CascadeType;
|
||||
import javax.persistence.FetchType;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.AnnotationValue;
|
||||
import org.jboss.jandex.DotName;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
import org.hibernate.mapping.PropertyGeneration;
|
||||
import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
|
||||
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
||||
import org.hibernate.metamodel.source.annotations.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.type.AttributeTypeResolver;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.type.AttributeTypeResolverImpl;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.type.CompositeAttributeTypeResolver;
|
||||
|
||||
/**
|
||||
* Represents an association attribute.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
* @todo Check whether we need further subclasses for different association types. Needs to evolve during development (HF)
|
||||
*/
|
||||
public class AssociationAttribute extends BasicAttribute {
|
||||
private final AttributeType associationType;
|
||||
public class AssociationAttribute extends MappedAttribute {
|
||||
private final AttributeNature associationNature;
|
||||
private final boolean ignoreNotFound;
|
||||
private final String referencedEntityType;
|
||||
private final String mappedBy;
|
||||
private final Set<CascadeType> cascadeTypes;
|
||||
private final boolean isOptional;
|
||||
private final boolean isLazy;
|
||||
private final boolean isOrphanRemoval;
|
||||
private final FetchMode fetchMode;
|
||||
|
||||
private boolean isInsertable = true;
|
||||
private boolean isUpdatable = true;
|
||||
private AttributeTypeResolver resolver;
|
||||
|
||||
public static AssociationAttribute createAssociationAttribute(String name,
|
||||
Class<?> attributeType,
|
||||
AttributeType attributeNature,
|
||||
AttributeNature attributeNature,
|
||||
String accessType,
|
||||
Map<DotName, List<AnnotationInstance>> annotations,
|
||||
AnnotationBindingContext context) {
|
||||
return new AssociationAttribute( name, attributeType, attributeNature, accessType, annotations, context );
|
||||
return new AssociationAttribute(
|
||||
name,
|
||||
attributeType,
|
||||
attributeNature,
|
||||
accessType,
|
||||
annotations,
|
||||
context
|
||||
);
|
||||
}
|
||||
|
||||
private AssociationAttribute(String name,
|
||||
Class<?> javaType,
|
||||
AttributeType associationType,
|
||||
AttributeNature associationType,
|
||||
String accessType,
|
||||
Map<DotName, List<AnnotationInstance>> annotations,
|
||||
AnnotationBindingContext context) {
|
||||
super( name, javaType, accessType, annotations, context );
|
||||
this.associationType = associationType;
|
||||
this.associationNature = associationType;
|
||||
this.ignoreNotFound = ignoreNotFound();
|
||||
|
||||
AnnotationInstance associationAnnotation = JandexHelper.getSingleAnnotation(
|
||||
|
@ -71,8 +96,15 @@ public class AssociationAttribute extends BasicAttribute {
|
|||
associationType.getAnnotationDotName()
|
||||
);
|
||||
|
||||
referencedEntityType = determineReferencedEntityType( associationAnnotation );
|
||||
cascadeTypes = determineCascadeTypes( associationAnnotation );
|
||||
// using jandex we don't really care which exact type of annotation we are dealing with
|
||||
this.referencedEntityType = determineReferencedEntityType( associationAnnotation );
|
||||
this.mappedBy = determineMappedByAttributeName( associationAnnotation );
|
||||
this.isOptional = determineOptionality( associationAnnotation );
|
||||
this.isLazy = determineFetchType( associationAnnotation );
|
||||
this.isOrphanRemoval = determineOrphanRemoval( associationAnnotation );
|
||||
this.cascadeTypes = determineCascadeTypes( associationAnnotation );
|
||||
|
||||
this.fetchMode = determineFetchMode();
|
||||
}
|
||||
|
||||
public boolean isIgnoreNotFound() {
|
||||
|
@ -83,14 +115,63 @@ public class AssociationAttribute extends BasicAttribute {
|
|||
return referencedEntityType;
|
||||
}
|
||||
|
||||
public AttributeType getAssociationType() {
|
||||
return associationType;
|
||||
public String getMappedBy() {
|
||||
return mappedBy;
|
||||
}
|
||||
|
||||
public AttributeNature getAssociationNature() {
|
||||
return associationNature;
|
||||
}
|
||||
|
||||
public Set<CascadeType> getCascadeTypes() {
|
||||
return cascadeTypes;
|
||||
}
|
||||
|
||||
public boolean isOrphanRemoval() {
|
||||
return isOrphanRemoval;
|
||||
}
|
||||
|
||||
public FetchMode getFetchMode() {
|
||||
return fetchMode;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AttributeTypeResolver getHibernateTypeResolver() {
|
||||
if ( resolver == null ) {
|
||||
resolver = getDefaultHibernateTypeResolver();
|
||||
}
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isLazy() {
|
||||
return isLazy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOptional() {
|
||||
return isOptional;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInsertable() {
|
||||
return isInsertable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUpdatable() {
|
||||
return isUpdatable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyGeneration getPropertyGeneration() {
|
||||
return PropertyGeneration.NEVER;
|
||||
}
|
||||
|
||||
private AttributeTypeResolver getDefaultHibernateTypeResolver() {
|
||||
return new CompositeAttributeTypeResolver( new AttributeTypeResolverImpl( this ) );
|
||||
}
|
||||
|
||||
private boolean ignoreNotFound() {
|
||||
NotFoundAction action = NotFoundAction.EXCEPTION;
|
||||
AnnotationInstance notFoundAnnotation = JandexHelper.getSingleAnnotation(
|
||||
|
@ -107,6 +188,38 @@ public class AssociationAttribute extends BasicAttribute {
|
|||
return NotFoundAction.IGNORE.equals( action );
|
||||
}
|
||||
|
||||
private boolean determineOptionality(AnnotationInstance associationAnnotation) {
|
||||
boolean optional = true;
|
||||
|
||||
AnnotationValue optionalValue = associationAnnotation.value( "optional" );
|
||||
if ( optionalValue != null ) {
|
||||
optional = optionalValue.asBoolean();
|
||||
}
|
||||
|
||||
return optional;
|
||||
}
|
||||
|
||||
private boolean determineOrphanRemoval(AnnotationInstance associationAnnotation) {
|
||||
boolean orphanRemoval = false;
|
||||
AnnotationValue orphanRemovalValue = associationAnnotation.value( "orphanRemoval" );
|
||||
if ( orphanRemovalValue != null ) {
|
||||
orphanRemoval = orphanRemovalValue.asBoolean();
|
||||
}
|
||||
return orphanRemoval;
|
||||
}
|
||||
|
||||
private boolean determineFetchType(AnnotationInstance associationAnnotation) {
|
||||
boolean lazy = false;
|
||||
AnnotationValue fetchValue = associationAnnotation.value( "fetch" );
|
||||
if ( fetchValue != null ) {
|
||||
FetchType fetchType = Enum.valueOf( FetchType.class, fetchValue.asEnum() );
|
||||
if ( FetchType.LAZY.equals( fetchType ) ) {
|
||||
lazy = true;
|
||||
}
|
||||
}
|
||||
return lazy;
|
||||
}
|
||||
|
||||
private String determineReferencedEntityType(AnnotationInstance associationAnnotation) {
|
||||
String targetTypeName = getAttributeType().getName();
|
||||
|
||||
|
@ -126,6 +239,16 @@ public class AssociationAttribute extends BasicAttribute {
|
|||
return targetTypeName;
|
||||
}
|
||||
|
||||
private String determineMappedByAttributeName(AnnotationInstance associationAnnotation) {
|
||||
String mappedBy = null;
|
||||
AnnotationValue mappedByAnnotationValue = associationAnnotation.value( "mappedBy" );
|
||||
if ( mappedByAnnotationValue != null ) {
|
||||
mappedBy = mappedByAnnotationValue.asString();
|
||||
}
|
||||
|
||||
return mappedBy;
|
||||
}
|
||||
|
||||
private Set<CascadeType> determineCascadeTypes(AnnotationInstance associationAnnotation) {
|
||||
Set<CascadeType> cascadeTypes = new HashSet<CascadeType>();
|
||||
AnnotationValue cascadeValue = associationAnnotation.value( "cascade" );
|
||||
|
@ -137,6 +260,21 @@ public class AssociationAttribute extends BasicAttribute {
|
|||
}
|
||||
return cascadeTypes;
|
||||
}
|
||||
|
||||
private FetchMode determineFetchMode() {
|
||||
FetchMode mode = FetchMode.DEFAULT;
|
||||
|
||||
AnnotationInstance fetchAnnotation = JandexHelper.getSingleAnnotation( annotations(), HibernateDotNames.FETCH );
|
||||
if ( fetchAnnotation != null ) {
|
||||
org.hibernate.annotations.FetchMode annotationFetchMode = JandexHelper.getEnumValue(
|
||||
fetchAnnotation,
|
||||
"value",
|
||||
org.hibernate.annotations.FetchMode.class
|
||||
);
|
||||
}
|
||||
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,19 +32,19 @@ import org.hibernate.metamodel.source.annotations.JPADotNames;
|
|||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public enum AttributeType {
|
||||
BASIC( null ),
|
||||
public enum AttributeNature {
|
||||
BASIC( JPADotNames.BASIC ),
|
||||
ONE_TO_ONE( JPADotNames.ONE_TO_ONE ),
|
||||
ONE_TO_MANY( JPADotNames.ONE_TO_MANY ),
|
||||
MANY_TO_ONE( JPADotNames.MANY_TO_ONE ),
|
||||
MANY_TO_MANY( JPADotNames.MANY_TO_MANY ),
|
||||
ELEMENT_COLLECTION( JPADotNames.ELEMENT_COLLECTION ),
|
||||
EMBEDDED_ID( JPADotNames.EMBEDDED_ID ),
|
||||
EMBEDDED_ID( JPADotNames.EMBEDDED_ID ),
|
||||
EMBEDDED( JPADotNames.EMBEDDED );
|
||||
|
||||
private final DotName annotationDotName;
|
||||
|
||||
AttributeType(DotName annotationDotName) {
|
||||
AttributeNature(DotName annotationDotName) {
|
||||
this.annotationDotName = annotationDotName;
|
||||
}
|
||||
|
|
@ -44,7 +44,7 @@ import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
|
|||
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.TypeEnumConversionHelper;
|
||||
import org.hibernate.metamodel.source.annotations.EnumConversionHelper;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.type.AttributeTypeResolver;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.type.CompositeAttributeTypeResolver;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.type.EnumeratedTypeResolver;
|
||||
|
@ -53,15 +53,11 @@ import org.hibernate.metamodel.source.annotations.attribute.type.LobTypeResolver
|
|||
import org.hibernate.metamodel.source.annotations.attribute.type.TemporalTypeResolver;
|
||||
|
||||
/**
|
||||
* Represent a mapped attribute (explicitly or implicitly mapped).
|
||||
* Represent a basic attribute (explicitly or implicitly mapped).
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class BasicAttribute extends MappedAttribute {
|
||||
/**
|
||||
* Is this property an id property (or part thereof).
|
||||
*/
|
||||
private final boolean isId;
|
||||
|
||||
/**
|
||||
* The id generator in case this basic attribute represents an simple id. Will be {@code null} in case there
|
||||
|
@ -74,12 +70,6 @@ public class BasicAttribute extends MappedAttribute {
|
|||
*/
|
||||
private final boolean isVersioned;
|
||||
|
||||
/**
|
||||
* 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}).
|
||||
*/
|
||||
|
@ -97,11 +87,6 @@ public class BasicAttribute extends MappedAttribute {
|
|||
private boolean isInsertable = true;
|
||||
private boolean isUpdatable = true;
|
||||
|
||||
/**
|
||||
* Defines the column values (relational values) for this property.
|
||||
*/
|
||||
private ColumnValues columnValues;
|
||||
|
||||
private final String customWriteFragment;
|
||||
private final String customReadFragment;
|
||||
private final String checkCondition;
|
||||
|
@ -122,32 +107,19 @@ public class BasicAttribute extends MappedAttribute {
|
|||
AnnotationBindingContext context) {
|
||||
super( name, attributeType, accessType, annotations, context );
|
||||
|
||||
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ID );
|
||||
AnnotationInstance embeddedIdAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.EMBEDDED_ID
|
||||
);
|
||||
//if this attribute has either @Id or @EmbeddedId, then it is an id attribute
|
||||
isId = ( idAnnotation != null || embeddedIdAnnotation != null );
|
||||
|
||||
AnnotationInstance versionAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.VERSION );
|
||||
isVersioned = versionAnnotation != null;
|
||||
|
||||
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.COLUMN );
|
||||
columnValues = new ColumnValues( columnAnnotation );
|
||||
|
||||
if ( isId ) {
|
||||
if ( isId() ) {
|
||||
// an id must be unique and cannot be nullable
|
||||
columnValues.setUnique( true );
|
||||
columnValues.setNullable( false );
|
||||
getColumnValues().setUnique( true );
|
||||
getColumnValues().setNullable( false );
|
||||
idGenerator = checkGeneratedValueAnnotation();
|
||||
}
|
||||
else {
|
||||
idGenerator = null;
|
||||
}
|
||||
|
||||
this.isOptimisticLockable = checkOptimisticLockAnnotation();
|
||||
|
||||
checkBasicAnnotation();
|
||||
checkGeneratedAnnotation();
|
||||
|
||||
|
@ -158,14 +130,6 @@ public class BasicAttribute extends MappedAttribute {
|
|||
this.checkCondition = parseCheckAnnotation();
|
||||
}
|
||||
|
||||
public final ColumnValues getColumnValues() {
|
||||
return columnValues;
|
||||
}
|
||||
|
||||
public boolean isId() {
|
||||
return isId;
|
||||
}
|
||||
|
||||
public boolean isVersioned() {
|
||||
return isVersioned;
|
||||
}
|
||||
|
@ -190,10 +154,6 @@ public class BasicAttribute extends MappedAttribute {
|
|||
return propertyGeneration;
|
||||
}
|
||||
|
||||
public boolean isOptimisticLockable() {
|
||||
return isOptimisticLockable;
|
||||
}
|
||||
|
||||
public String getCustomWriteFragment() {
|
||||
return customWriteFragment;
|
||||
}
|
||||
|
@ -218,19 +178,6 @@ public class BasicAttribute extends MappedAttribute {
|
|||
return sb.toString();
|
||||
}
|
||||
|
||||
private boolean checkOptimisticLockAnnotation() {
|
||||
boolean triggersVersionIncrement = true;
|
||||
AnnotationInstance optimisticLockAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations(),
|
||||
HibernateDotNames.OPTIMISTIC_LOCK
|
||||
);
|
||||
if ( optimisticLockAnnotation != null ) {
|
||||
boolean exclude = optimisticLockAnnotation.value( "excluded" ).asBoolean();
|
||||
triggersVersionIncrement = !exclude;
|
||||
}
|
||||
return triggersVersionIncrement;
|
||||
}
|
||||
|
||||
private void checkBasicAnnotation() {
|
||||
AnnotationInstance basicAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.BASIC );
|
||||
if ( basicAnnotation != null ) {
|
||||
|
@ -346,7 +293,7 @@ public class BasicAttribute extends MappedAttribute {
|
|||
"strategy",
|
||||
GenerationType.class
|
||||
);
|
||||
String strategy = TypeEnumConversionHelper.generationTypeToGeneratorStrategyName(
|
||||
String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName(
|
||||
genType,
|
||||
getContext().getMetadataImplementor().getOptions().useNewIdentifierGenerators()
|
||||
);
|
||||
|
|
|
@ -29,13 +29,13 @@ import org.hibernate.internal.util.StringHelper;
|
|||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class ColumnSourceImpl extends ColumnValuesSourceImpl {
|
||||
private final BasicAttribute attribute;
|
||||
private final MappedAttribute attribute;
|
||||
private final String name;
|
||||
|
||||
ColumnSourceImpl(BasicAttribute attribute, AttributeOverride attributeOverride) {
|
||||
ColumnSourceImpl(MappedAttribute attribute, AttributeOverride attributeOverride) {
|
||||
super( attribute.getColumnValues() );
|
||||
if(attributeOverride != null) {
|
||||
setOverrideColumnValues( attributeOverride.getColumnValues() );
|
||||
if ( attributeOverride != null ) {
|
||||
setOverrideColumnValues( attributeOverride.getColumnValues() );
|
||||
}
|
||||
this.attribute = attribute;
|
||||
this.name = resolveColumnName();
|
||||
|
@ -58,17 +58,32 @@ public class ColumnSourceImpl extends ColumnValuesSourceImpl {
|
|||
|
||||
@Override
|
||||
public String getReadFragment() {
|
||||
return attribute.getCustomReadFragment();
|
||||
if ( attribute instanceof BasicAttribute ) {
|
||||
return ( (BasicAttribute) attribute ).getCustomReadFragment();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWriteFragment() {
|
||||
return attribute.getCustomWriteFragment();
|
||||
if ( attribute instanceof BasicAttribute ) {
|
||||
return ( (BasicAttribute) attribute ).getCustomWriteFragment();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCheckCondition() {
|
||||
return attribute.getCheckCondition();
|
||||
if ( attribute instanceof BasicAttribute ) {
|
||||
return ( (BasicAttribute) attribute ).getCheckCondition();
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,11 @@ import java.util.Map;
|
|||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.DotName;
|
||||
|
||||
import org.hibernate.mapping.PropertyGeneration;
|
||||
import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
|
||||
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.type.AttributeTypeResolver;
|
||||
|
||||
/**
|
||||
|
@ -59,6 +63,22 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
*/
|
||||
private final String accessType;
|
||||
|
||||
/**
|
||||
* Defines the column values (relational values) for this property.
|
||||
*/
|
||||
private ColumnValues columnValues;
|
||||
|
||||
/**
|
||||
* Is this property an id property (or part thereof).
|
||||
*/
|
||||
private final boolean isId;
|
||||
|
||||
/**
|
||||
* Whether a change of the property's value triggers a version increment of the entity (in case of optimistic
|
||||
* locking).
|
||||
*/
|
||||
private final boolean isOptimisticLockable;
|
||||
|
||||
/**
|
||||
* The binding context
|
||||
*/
|
||||
|
@ -70,6 +90,22 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
this.name = name;
|
||||
this.attributeType = attributeType;
|
||||
this.accessType = accessType;
|
||||
|
||||
//if this attribute has either @Id or @EmbeddedId, then it is an id attribute
|
||||
AnnotationInstance idAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ID );
|
||||
AnnotationInstance embeddedIdAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.EMBEDDED_ID
|
||||
);
|
||||
isId = ( idAnnotation != null || embeddedIdAnnotation != null );
|
||||
|
||||
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.COLUMN
|
||||
);
|
||||
columnValues = new ColumnValues( columnAnnotation );
|
||||
|
||||
this.isOptimisticLockable = checkOptimisticLockAnnotation();
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
|
@ -92,13 +128,23 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
return annotations;
|
||||
}
|
||||
|
||||
public ColumnValues getColumnValues() {
|
||||
return columnValues;
|
||||
}
|
||||
|
||||
public boolean isId() {
|
||||
return isId;
|
||||
}
|
||||
|
||||
public boolean isOptimisticLockable() {
|
||||
return isOptimisticLockable;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MappedAttribute mappedProperty) {
|
||||
return name.compareTo( mappedProperty.getName() );
|
||||
}
|
||||
|
||||
public abstract AttributeTypeResolver getHibernateTypeResolver();
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
|
@ -107,6 +153,31 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public abstract AttributeTypeResolver getHibernateTypeResolver();
|
||||
|
||||
public abstract boolean isLazy();
|
||||
|
||||
public abstract boolean isOptional();
|
||||
|
||||
public abstract boolean isInsertable();
|
||||
|
||||
public abstract boolean isUpdatable();
|
||||
|
||||
public abstract PropertyGeneration getPropertyGeneration();
|
||||
|
||||
private boolean checkOptimisticLockAnnotation() {
|
||||
boolean triggersVersionIncrement = true;
|
||||
AnnotationInstance optimisticLockAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations(),
|
||||
HibernateDotNames.OPTIMISTIC_LOCK
|
||||
);
|
||||
if ( optimisticLockAnnotation != null ) {
|
||||
boolean exclude = optimisticLockAnnotation.value( "excluded" ).asBoolean();
|
||||
triggersVersionIncrement = !exclude;
|
||||
}
|
||||
return triggersVersionIncrement;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -38,14 +38,14 @@ import org.hibernate.metamodel.source.binder.SingularAttributeSource;
|
|||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class SingularAttributeSourceImpl implements SingularAttributeSource {
|
||||
private final BasicAttribute attribute;
|
||||
private final MappedAttribute attribute;
|
||||
private final AttributeOverride attributeOverride;
|
||||
|
||||
public SingularAttributeSourceImpl(BasicAttribute attribute) {
|
||||
public SingularAttributeSourceImpl(MappedAttribute attribute) {
|
||||
this(attribute, null);
|
||||
}
|
||||
|
||||
public SingularAttributeSourceImpl(BasicAttribute attribute, AttributeOverride attributeOverride) {
|
||||
public SingularAttributeSourceImpl(MappedAttribute attribute, AttributeOverride attributeOverride) {
|
||||
this.attribute = attribute;
|
||||
this.attributeOverride = attributeOverride;
|
||||
}
|
||||
|
@ -117,7 +117,6 @@ public class SingularAttributeSourceImpl implements SingularAttributeSource {
|
|||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean areValuesIncludedInInsertByDefault() {
|
||||
return true;
|
||||
|
|
|
@ -23,11 +23,11 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.source.annotations.attribute;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import org.hibernate.FetchMode;
|
||||
import org.hibernate.engine.spi.CascadeStyle;
|
||||
import org.hibernate.metamodel.source.annotations.EnumConversionHelper;
|
||||
import org.hibernate.metamodel.source.binder.SingularAttributeNature;
|
||||
import org.hibernate.metamodel.source.binder.ToOneAttributeSource;
|
||||
|
||||
|
@ -36,15 +36,12 @@ import org.hibernate.metamodel.source.binder.ToOneAttributeSource;
|
|||
*/
|
||||
public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implements ToOneAttributeSource {
|
||||
private final AssociationAttribute associationAttribute;
|
||||
private final Set<CascadeStyle> cascadeStyles = new HashSet<CascadeStyle>();
|
||||
private final Set<CascadeStyle> cascadeStyles;
|
||||
|
||||
public ToOneAttributeSourceImpl(AssociationAttribute associationAttribute) {
|
||||
super( associationAttribute );
|
||||
this.associationAttribute = associationAttribute;
|
||||
|
||||
for ( javax.persistence.CascadeType cascadeType : associationAttribute.getCascadeTypes() ) {
|
||||
// todo : ...
|
||||
}
|
||||
this.cascadeStyles = EnumConversionHelper.cascadeTypeToCascadeStyleSet( associationAttribute.getCascadeTypes() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -59,7 +56,7 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem
|
|||
|
||||
@Override
|
||||
public String getReferencedEntityAttributeName() {
|
||||
return null;
|
||||
return associationAttribute.getMappedBy();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,8 +66,7 @@ public class ToOneAttributeSourceImpl extends SingularAttributeSourceImpl implem
|
|||
|
||||
@Override
|
||||
public FetchMode getFetchMode() {
|
||||
// todo : implement
|
||||
return FetchMode.DEFAULT;
|
||||
return associationAttribute.getFetchMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,8 +61,8 @@ import org.hibernate.metamodel.source.annotations.JPADotNames;
|
|||
import org.hibernate.metamodel.source.annotations.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.ReflectionHelper;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.AssociationAttribute;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.AttributeNature;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.AttributeOverride;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.AttributeType;
|
||||
import org.hibernate.metamodel.source.annotations.attribute.BasicAttribute;
|
||||
|
||||
/**
|
||||
|
@ -181,10 +181,6 @@ public class ConfiguredClass {
|
|||
return localBindingContext;
|
||||
}
|
||||
|
||||
public ConfiguredClassType getConfiguredClassType() {
|
||||
return configuredClassType;
|
||||
}
|
||||
|
||||
public Iterable<BasicAttribute> getSimpleAttributes() {
|
||||
return simpleAttributeMap.values();
|
||||
}
|
||||
|
@ -446,7 +442,7 @@ public class ConfiguredClass {
|
|||
classInfo, member.getName()
|
||||
);
|
||||
|
||||
AttributeType attributeNature = determineAttributeType( annotations );
|
||||
AttributeNature attributeNature = determineAttributeNature( annotations );
|
||||
String accessTypeString = accessType.toString().toLowerCase();
|
||||
switch ( attributeNature ) {
|
||||
case BASIC: {
|
||||
|
@ -457,8 +453,7 @@ public class ConfiguredClass {
|
|||
idAttributeMap.put( attributeName, attribute );
|
||||
}
|
||||
else if ( attribute.isVersioned() ) {
|
||||
if (
|
||||
versionAttribute == null ) {
|
||||
if ( versionAttribute == null ) {
|
||||
versionAttribute = attribute;
|
||||
}
|
||||
else {
|
||||
|
@ -489,7 +484,7 @@ public class ConfiguredClass {
|
|||
resolveEmbeddable( attributeName, attributeType );
|
||||
break;
|
||||
}
|
||||
// TODO handle the different association types
|
||||
// OneToOne, OneToMany, ManyToOne, ManyToMany
|
||||
default: {
|
||||
AssociationAttribute attribute = AssociationAttribute.createAssociationAttribute(
|
||||
attributeName,
|
||||
|
@ -534,38 +529,38 @@ public class ConfiguredClass {
|
|||
*
|
||||
* @return an instance of the {@code AttributeType} enum
|
||||
*/
|
||||
private AttributeType determineAttributeType(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
EnumMap<AttributeType, AnnotationInstance> discoveredAttributeTypes =
|
||||
new EnumMap<AttributeType, AnnotationInstance>( AttributeType.class );
|
||||
private AttributeNature determineAttributeNature(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
EnumMap<AttributeNature, AnnotationInstance> discoveredAttributeTypes =
|
||||
new EnumMap<AttributeNature, AnnotationInstance>( AttributeNature.class );
|
||||
|
||||
AnnotationInstance oneToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE );
|
||||
if ( oneToOne != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.ONE_TO_ONE, oneToOne );
|
||||
discoveredAttributeTypes.put( AttributeNature.ONE_TO_ONE, oneToOne );
|
||||
}
|
||||
|
||||
AnnotationInstance oneToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY );
|
||||
if ( oneToMany != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.ONE_TO_MANY, oneToMany );
|
||||
discoveredAttributeTypes.put( AttributeNature.ONE_TO_MANY, oneToMany );
|
||||
}
|
||||
|
||||
AnnotationInstance manyToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_ONE );
|
||||
if ( manyToOne != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.MANY_TO_ONE, manyToOne );
|
||||
discoveredAttributeTypes.put( AttributeNature.MANY_TO_ONE, manyToOne );
|
||||
}
|
||||
|
||||
AnnotationInstance manyToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY );
|
||||
if ( manyToMany != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.MANY_TO_MANY, manyToMany );
|
||||
discoveredAttributeTypes.put( AttributeNature.MANY_TO_MANY, manyToMany );
|
||||
}
|
||||
|
||||
AnnotationInstance embedded = JandexHelper.getSingleAnnotation( annotations, JPADotNames.EMBEDDED );
|
||||
if ( embedded != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.EMBEDDED, embedded );
|
||||
discoveredAttributeTypes.put( AttributeNature.EMBEDDED, embedded );
|
||||
}
|
||||
|
||||
AnnotationInstance embeddIded = JandexHelper.getSingleAnnotation( annotations, JPADotNames.EMBEDDED_ID );
|
||||
if ( embeddIded != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.EMBEDDED_ID, embeddIded );
|
||||
AnnotationInstance embeddedId = JandexHelper.getSingleAnnotation( annotations, JPADotNames.EMBEDDED_ID );
|
||||
if ( embeddedId != null ) {
|
||||
discoveredAttributeTypes.put( AttributeNature.EMBEDDED_ID, embeddedId );
|
||||
}
|
||||
|
||||
AnnotationInstance elementCollection = JandexHelper.getSingleAnnotation(
|
||||
|
@ -573,11 +568,11 @@ public class ConfiguredClass {
|
|||
JPADotNames.ELEMENT_COLLECTION
|
||||
);
|
||||
if ( elementCollection != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.ELEMENT_COLLECTION, elementCollection );
|
||||
discoveredAttributeTypes.put( AttributeNature.ELEMENT_COLLECTION, elementCollection );
|
||||
}
|
||||
|
||||
if ( discoveredAttributeTypes.size() == 0 ) {
|
||||
return AttributeType.BASIC;
|
||||
return AttributeNature.BASIC;
|
||||
}
|
||||
else if ( discoveredAttributeTypes.size() == 1 ) {
|
||||
return discoveredAttributeTypes.keySet().iterator().next();
|
||||
|
|
|
@ -311,13 +311,11 @@ public class EntityClass extends ConfiguredClass {
|
|||
idAnnotationList.addAll( getClassInfo().annotations().get( idAnnotationType ) );
|
||||
}
|
||||
ConfiguredClass parent = getParent();
|
||||
while ( parent != null && ( ConfiguredClassType.MAPPED_SUPERCLASS.equals( parent.getConfiguredClassType() ) ||
|
||||
ConfiguredClassType.NON_ENTITY.equals( parent.getConfiguredClassType() ) ) ) {
|
||||
while ( parent != null ) {
|
||||
if ( parent.getClassInfo().annotations().get( idAnnotationType ) != null ) {
|
||||
idAnnotationList.addAll( parent.getClassInfo().annotations().get( idAnnotationType ) );
|
||||
}
|
||||
parent = parent.getParent();
|
||||
|
||||
}
|
||||
return idAnnotationList;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ import org.hibernate.metamodel.source.annotations.AnnotationBindingContext;
|
|||
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.TypeEnumConversionHelper;
|
||||
import org.hibernate.metamodel.source.annotations.EnumConversionHelper;
|
||||
|
||||
/**
|
||||
* Binds {@link SequenceGenerator}, {@link javax.persistence.TableGenerator}, {@link GenericGenerator}, and
|
||||
|
@ -141,7 +141,7 @@ public class IdGeneratorBinder {
|
|||
Map<String, String> parameterMap = new HashMap<String, String>();
|
||||
addStringParameter( generator, "sequenceName", parameterMap, SequenceStyleGenerator.SEQUENCE_PARAM );
|
||||
boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators();
|
||||
String strategy = TypeEnumConversionHelper.generationTypeToGeneratorStrategyName(
|
||||
String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName(
|
||||
GenerationType.SEQUENCE,
|
||||
useNewIdentifierGenerators
|
||||
);
|
||||
|
@ -176,7 +176,7 @@ public class IdGeneratorBinder {
|
|||
addStringParameter( generator, "catalog", parameterMap, PersistentIdentifierGenerator.CATALOG );
|
||||
addStringParameter( generator, "schema", parameterMap, PersistentIdentifierGenerator.SCHEMA );
|
||||
boolean useNewIdentifierGenerators = metadata.getOptions().useNewIdentifierGenerators();
|
||||
String strategy = TypeEnumConversionHelper.generationTypeToGeneratorStrategyName(
|
||||
String strategy = EnumConversionHelper.generationTypeToGeneratorStrategyName(
|
||||
GenerationType.TABLE,
|
||||
useNewIdentifierGenerators
|
||||
);
|
||||
|
|
|
@ -110,5 +110,6 @@ public interface ColumnSource extends RelationalValueSource {
|
|||
public String getComment();
|
||||
|
||||
public boolean isIncludedInInsert();
|
||||
|
||||
public boolean isIncludedInUpdate();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue