From 1b1af382de8bd83d260bf0821ec004a8ae2dd135 Mon Sep 17 00:00:00 2001 From: Strong Liu Date: Tue, 26 Jun 2012 14:04:26 +0800 Subject: [PATCH] HHH-7384 binding natural id cache HHH-6354 Implement natural ID mapping --- .../internal/SessionFactoryImpl.java | 37 +++++++++++ .../hibernate/metamodel/internal/Binder.java | 4 ++ .../annotations/attribute/BasicAttribute.java | 7 +-- .../attribute/MappedAttribute.java | 27 +++++++- .../SingularAttributeSourceImpl.java | 5 +- .../attribute/ToOneAttributeSourceImpl.java | 13 +--- .../attribute/VersionAttributeSourceImpl.java | 6 ++ .../entity/ComponentAttributeSourceImpl.java | 13 ++-- .../annotations/entity/ConfiguredClass.java | 61 +++++++++++-------- .../annotations/entity/EmbeddableClass.java | 15 +++-- .../entity/EmbeddableHierarchy.java | 22 ++++--- .../annotations/entity/EntityClass.java | 31 ++++++++++ .../entity/RootEntitySourceImpl.java | 5 ++ .../annotations/util/HibernateDotNames.java | 2 + .../AbstractComponentAttributeSourceImpl.java | 7 ++- .../source/hbm/AbstractEntitySourceImpl.java | 10 +-- .../AbstractPluralAttributeSourceImpl.java | 10 +-- .../hbm/ComponentAttributeSourceImpl.java | 3 +- .../metamodel/internal/source/hbm/Helper.java | 43 +++++++++---- .../hbm/ManyToOneAttributeSourceImpl.java | 7 ++- .../hbm/PropertyAttributeSourceImpl.java | 7 ++- .../source/hbm/RootEntitySourceImpl.java | 26 +++++--- ...SingularIdentifierAttributeSourceImpl.java | 6 +- .../hbm/TimestampAttributeSourceImpl.java | 5 +- .../hbm/VersionAttributeSourceImpl.java | 5 +- .../AbstractSingularAttributeBinding.java | 8 +++ .../binding/AttributeBindingContainer.java | 3 + .../spi/binding/BackRefAttributeBinding.java | 5 +- .../spi/binding/BasicAttributeBinding.java | 2 + .../binding/CompositeAttributeBinding.java | 12 ++++ .../metamodel/spi/binding/EntityBinding.java | 7 +++ .../spi/binding/HierarchyDetails.java | 9 +++ .../binding/ManyToOneAttributeBinding.java | 2 + .../spi/binding/SingularAttributeBinding.java | 14 +++++ .../spi/source/RootEntitySource.java | 7 +++ .../spi/source/SingularAttributeSource.java | 8 +-- .../tuple/entity/EntityMetamodel.java | 22 +++---- .../util/BaseAnnotationIndexTestCase.java | 6 +- .../util/EmbeddableHierarchyTest.java | 6 +- .../spi/binding/SimpleValueBindingTests.java | 1 + 40 files changed, 354 insertions(+), 135 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java index 0f5fb167a6..3fffd0a07b 100644 --- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java @@ -746,6 +746,43 @@ public void sessionFactoryClosed(SessionFactory factory) { allCacheRegions.put( cacheRegionName, entityRegion ); } } + + NaturalIdRegionAccessStrategy naturalIdAccessStrategy = null; + if ( settings.isSecondLevelCacheEnabled() && + rootEntityBinding.getHierarchyDetails().getNaturalIdCaching() != null && + model.getHierarchyDetails().getNaturalIdCaching() != null ) { + final String naturalIdCacheRegionName = cacheRegionPrefix + rootEntityBinding.getHierarchyDetails() + .getNaturalIdCaching() + .getRegion(); + naturalIdAccessStrategy = (NaturalIdRegionAccessStrategy) entityAccessStrategies.get( + naturalIdCacheRegionName + ); + if ( naturalIdAccessStrategy == null ) { + final CacheDataDescriptionImpl naturaIdCacheDataDescription = CacheDataDescriptionImpl.decode( model ); + NaturalIdRegion naturalIdRegion = null; + try { + naturalIdRegion = settings.getRegionFactory() + .buildNaturalIdRegion( + naturalIdCacheRegionName, + properties, + naturaIdCacheDataDescription + ); + } + catch ( UnsupportedOperationException e ) { + LOG.warnf( + "Shared cache region factory [%s] does not support natural id caching; " + + "shared NaturalId caching will be disabled for not be enabled for %s", + settings.getRegionFactory().getClass().getName(), + model.getEntity().getName() + ); + } + if ( naturalIdRegion != null ) { + naturalIdAccessStrategy = naturalIdRegion.buildAccessStrategy( settings.getRegionFactory().getDefaultAccessType() ); + entityAccessStrategies.put( naturalIdCacheRegionName, naturalIdAccessStrategy ); + allCacheRegions.put( naturalIdCacheRegionName, naturalIdRegion ); + } + } + } EntityPersister cp = serviceRegistry.getService( PersisterFactory.class ).createEntityPersister( model, accessStrategy, this, metadata ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java index ee595640a4..89baa13ad0 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/Binder.java @@ -279,6 +279,7 @@ private BasicAttributeBinding bindBasicAttribute( propertyAccessorName( attributeSource ), attributeSource.isIncludedInOptimisticLocking(), attributeSource.isLazy(), + attributeSource.getNaturalIdMutability(), createMetaAttributeContext( attributeBindingContainer, attributeSource ), attributeSource.getGeneration() ); final HibernateTypeDescriptor hibernateTypeDescriptor = attributeBinding.getHibernateTypeDescriptor(); @@ -326,6 +327,7 @@ private CompositeAttributeBinding bindComponentAttribute( propertyAccessorName( attributeSource ), attributeSource.isIncludedInOptimisticLocking(), attributeSource.isLazy(), + attributeSource.getNaturalIdMutability(), createMetaAttributeContext( attributeBindingContainer, attributeSource ) ); bindAttributes( attributeBinding, attributeSource ); return attributeBinding; @@ -387,6 +389,7 @@ private ManyToOneAttributeBinding bindManyToOneAttribute( propertyAccessorName( attributeSource ), attributeSource.isIncludedInOptimisticLocking(), attributeSource.isLazy(), + attributeSource.getNaturalIdMutability(), createMetaAttributeContext( attributeBindingContainer, attributeSource ), ( SingularAttributeBinding ) referencedAttributeBinding, relationalValueBindings ); @@ -1001,6 +1004,7 @@ private EntityBinding bindEntities( final EntityHierarchy entityHierarchy ) { bindIdentifierGenerator( rootEntityBinding ); bindMultiTenancy( rootEntityBinding, rootEntitySource ); rootEntityBinding.getHierarchyDetails().setCaching( rootEntitySource.getCaching() ); + rootEntityBinding.getHierarchyDetails().setNaturalIdCaching( rootEntitySource.getNaturalIdCaching() ); rootEntityBinding.getHierarchyDetails().setExplicitPolymorphism( rootEntitySource.isExplicitPolymorphism() ); rootEntityBinding.getHierarchyDetails().setOptimisticLockStyle( rootEntitySource.getOptimisticLockStyle() ); rootEntityBinding.setMutable( rootEntitySource.isMutable() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java index 67aa0627ac..aabc00b8f9 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/BasicAttribute.java @@ -124,12 +124,7 @@ public static BasicAttribute createSimpleAttribute(String name, annotations, HibernateDotNames.SOURCE ); - if ( sourceAnnotation != null ) { - versionSourceType = JandexHelper.getEnumValue( sourceAnnotation, "value", SourceType.class ); - } - else { - versionSourceType = null; - } + this.versionSourceType = sourceAnnotation !=null ? JandexHelper.getEnumValue( sourceAnnotation, "value", SourceType.class ) : null; } else { versionSourceType = null; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/MappedAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/MappedAttribute.java index d8438e17d6..f83fe5f552 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/MappedAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/MappedAttribute.java @@ -37,6 +37,7 @@ import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; import org.hibernate.metamodel.internal.source.annotations.attribute.type.AttributeTypeResolver; import org.hibernate.metamodel.internal.source.annotations.entity.EntityBindingContext; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; /** * Base class for the different types of mapped attributes @@ -81,6 +82,11 @@ public abstract class MappedAttribute implements Comparable { */ private final boolean isId; + /** + * Is this property a natural id property and what's the mutability it is. + */ + private final SingularAttributeBinding.NaturalIdMutability naturalIdMutability; + /** * Whether a change of the property's value triggers a version increment of the entity (in case of optimistic * locking). @@ -98,7 +104,9 @@ public abstract class MappedAttribute implements Comparable { */ private final EntityBindingContext context; - MappedAttribute(String name, Class attributeType, AttributeNature attributeNature, String accessType, Map> annotations, EntityBindingContext context) { + MappedAttribute(String name, Class attributeType, AttributeNature attributeNature, + String accessType, Map> annotations, + EntityBindingContext context) { this.context = context; this.annotations = annotations; this.name = name; @@ -116,6 +124,7 @@ public abstract class MappedAttribute implements Comparable { this.isOptimisticLockable = checkOptimisticLockAnnotation(); this.checkCondition = checkCheckAnnotation(); + this.naturalIdMutability = checkNaturalId(); checkColumnAnnotations( annotations ); } @@ -151,6 +160,10 @@ public boolean isOptimisticLockable() { return isOptimisticLockable; } + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { + return naturalIdMutability; + } + public AttributeNature getAttributeNature() { return attributeNature; } @@ -198,6 +211,18 @@ private boolean checkOptimisticLockAnnotation() { return triggersVersionIncrement; } + private SingularAttributeBinding.NaturalIdMutability checkNaturalId() { + final AnnotationInstance naturalIdAnnotation = JandexHelper.getSingleAnnotation( + annotations, + HibernateDotNames.NATURAL_ID + ); + if ( naturalIdAnnotation == null ) { + return SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; + } + final boolean mutable = naturalIdAnnotation.value("mutable") == null ? false : naturalIdAnnotation.value( "mutable" ).asBoolean(); + return mutable ? SingularAttributeBinding.NaturalIdMutability.MUTABLE : SingularAttributeBinding.NaturalIdMutability.IMMUTABLE; + } + private void checkColumnAnnotations(Map> annotations) { columnValues = new ArrayList(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/SingularAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/SingularAttributeSourceImpl.java index 599753a015..161190f4fc 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/SingularAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/SingularAttributeSourceImpl.java @@ -29,6 +29,7 @@ import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.internal.source.annotations.attribute.type.ExplicitHibernateTypeSourceImpl; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.MetaAttributeSource; import org.hibernate.metamodel.spi.source.RelationalValueSource; @@ -72,8 +73,8 @@ public boolean isLazy() { } @Override - public NaturalIdMutability getNaturalIdMutability() { - return null; // todo : implement proper method body + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { + return attribute.getNaturalIdMutability(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/ToOneAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/ToOneAttributeSourceImpl.java index 4ec9a5c514..75ced50b26 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/ToOneAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/ToOneAttributeSourceImpl.java @@ -36,6 +36,7 @@ import org.hibernate.metamodel.internal.source.annotations.util.EnumConversionHelper; import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.source.ForeignKeyContributingSource; import org.hibernate.metamodel.spi.source.SingularAttributeNature; @@ -59,11 +60,6 @@ public SingularAttributeNature getNature() { return SingularAttributeNature.MANY_TO_ONE; } - @Override - public NaturalIdMutability getNaturalIdMutability() { - return null; // todo : implement proper method body - } - @Override public String getReferencedEntityName() { return associationAttribute.getReferencedEntityType(); @@ -111,12 +107,7 @@ public FetchMode getFetchMode() { @Override public FetchTiming getFetchTiming() { - if ( associationAttribute.isLazy() ) { - return FetchTiming.DELAYED; - } - else { - return FetchTiming.IMMEDIATE; - } + return associationAttribute.isLazy() ? FetchTiming.DELAYED : FetchTiming.IMMEDIATE; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/VersionAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/VersionAttributeSourceImpl.java index 9162d54f5a..d1d67311b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/VersionAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/attribute/VersionAttributeSourceImpl.java @@ -23,6 +23,7 @@ */ package org.hibernate.metamodel.internal.source.annotations.attribute; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.VersionAttributeSource; /** @@ -44,4 +45,9 @@ public VersionAttributeSourceImpl(MappedAttribute attribute, AttributeOverride a public String getUnsavedValue() { return null; } + + @Override + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { + return SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ComponentAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ComponentAttributeSourceImpl.java index c3a5ffb169..3908fbf9c1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ComponentAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ComponentAttributeSourceImpl.java @@ -32,6 +32,7 @@ import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.Value; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.LocalBindingContext; import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute; import org.hibernate.metamodel.internal.source.annotations.attribute.AttributeOverride; @@ -44,7 +45,6 @@ import org.hibernate.metamodel.spi.source.MetaAttributeSource; import org.hibernate.metamodel.spi.source.RelationalValueSource; import org.hibernate.metamodel.spi.source.SingularAttributeNature; -import org.hibernate.metamodel.spi.source.SingularAttributeSource; /** * Annotation backed implementation of {@code ComponentAttributeSource}. @@ -63,12 +63,7 @@ public ComponentAttributeSourceImpl(EmbeddableClass embeddableClass, String pare this.embeddableClass = embeddableClass; this.classReference = new Value>( embeddableClass.getConfiguredClass() ); this.attributeOverrides = attributeOverrides; - if ( StringHelper.isEmpty( parentPath ) ) { - path = embeddableClass.getEmbeddedAttributeName(); - } - else { - path = parentPath + "." + embeddableClass.getEmbeddedAttributeName(); - } + this.path = StringHelper.isEmpty( parentPath ) ? embeddableClass.getEmbeddedAttributeName() : parentPath + "." + embeddableClass.getEmbeddedAttributeName(); } @Override @@ -190,8 +185,8 @@ public boolean isLazy() { } @Override - public NaturalIdMutability getNaturalIdMutability() { - return null; // todo : implement proper method body + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { + return embeddableClass.getNaturalIdMutability(); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ConfiguredClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ConfiguredClass.java index ed9b4f98cf..748ae9e91b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ConfiguredClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/ConfiguredClass.java @@ -59,6 +59,7 @@ import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames; import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper; import org.hibernate.metamodel.internal.source.annotations.util.ReflectionHelper; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.MappingException; import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext; import org.hibernate.metamodel.internal.source.annotations.attribute.AssociationAttribute; @@ -365,7 +366,7 @@ private boolean isExplicitAttributeAccessAnnotationPlacedCorrectly(AnnotationTar // when the access type of the class is FIELD // overriding access annotations must be placed on properties AND have the access type PROPERTY if ( AccessType.FIELD.equals( classAccessType ) ) { - if ( !( annotationTarget instanceof MethodInfo ) ) { + if ( !MethodInfo.class.isInstance( annotationTarget ) ) { LOG.tracef( "The access type of class %s is AccessType.FIELD. To override the access for an attribute " + "@Access has to be placed on the property (getter)", classInfo.name().toString() @@ -387,7 +388,7 @@ private boolean isExplicitAttributeAccessAnnotationPlacedCorrectly(AnnotationTar // when the access type of the class is PROPERTY // overriding access annotations must be placed on fields and have the access type FIELD if ( AccessType.PROPERTY.equals( classAccessType ) ) { - if ( !( annotationTarget instanceof FieldInfo ) ) { + if ( !FieldInfo.class.isInstance( annotationTarget ) ) { LOG.tracef( "The access type of class %s is AccessType.PROPERTY. To override the access for a field " + "@Access has to be placed on the field ", classInfo.name().toString() @@ -410,13 +411,7 @@ private boolean isExplicitAttributeAccessAnnotationPlacedCorrectly(AnnotationTar private void createMappedAttribute(Member member, ResolvedTypeWithMembers resolvedType, AccessType accessType) { final String attributeName = ReflectionHelper.getPropertyName( member ); - ResolvedMember[] resolvedMembers; - if ( member instanceof Field ) { - resolvedMembers = resolvedType.getMemberFields(); - } - else { - resolvedMembers = resolvedType.getMemberMethods(); - } + final ResolvedMember[] resolvedMembers = Field.class.isInstance( member ) ? resolvedType.getMemberFields() : resolvedType.getMemberMethods(); Class attributeType = (Class) findResolvedType( member.getName(), resolvedMembers ); final Map> annotations = JandexHelper.getMemberAnnotations( classInfo, member.getName() @@ -449,13 +444,13 @@ else if ( attribute.isVersioned() ) { throw new NotYetImplementedException( "Element collections must still be implemented." ); } case EMBEDDED_ID: { - BasicAttribute attribute = BasicAttribute.createSimpleAttribute( + final BasicAttribute attribute = BasicAttribute.createSimpleAttribute( attributeName, attributeType, attributeNature, annotations, accessTypeString, getLocalBindingContext() ); idAttributeMap.put( attributeName, attribute ); } case EMBEDDED: { - AnnotationInstance targetAnnotation = JandexHelper.getSingleAnnotation( + final AnnotationInstance targetAnnotation = JandexHelper.getSingleAnnotation( getClassInfo(), HibernateDotNames.TARGET ); @@ -464,13 +459,13 @@ attributeName, attributeType, attributeNature, annotations, accessTypeString, ge JandexHelper.getValue( targetAnnotation, "value", String.class ) ); } - resolveEmbeddable( attributeName, attributeType ); + resolveEmbeddable( attributeName, attributeType, annotations ); break; } // OneToOne, OneToMany, ManyToOne, ManyToMany case ONE_TO_ONE: case MANY_TO_ONE: { - AssociationAttribute attribute = AssociationAttribute.createAssociationAttribute( + final AssociationAttribute attribute = AssociationAttribute.createAssociationAttribute( attributeName, attributeType, attributeNature, @@ -498,10 +493,10 @@ attributeName, attributeType, attributeNature, annotations, accessTypeString, ge } } - private void resolveEmbeddable(String attributeName, Class type) { - ClassInfo embeddableClassInfo = localBindingContext.getClassInfo( type.getName() ); + private void resolveEmbeddable(String attributeName, Class type, Map> annotations) { + final ClassInfo embeddableClassInfo = localBindingContext.getClassInfo( type.getName() ); if ( embeddableClassInfo == null ) { - String msg = String.format( + final String msg = String.format( "Attribute '%s#%s' is annotated with @Embedded, but '%s' does not seem to be annotated " + "with @Embeddable. Are all annotated classes added to the configuration?", getConfiguredClass().getSimpleName(), @@ -512,10 +507,26 @@ private void resolveEmbeddable(String attributeName, Class type) { } localBindingContext.resolveAllTypes( type.getName() ); - EmbeddableHierarchy hierarchy = EmbeddableHierarchy.createEmbeddableHierarchy( + AnnotationInstance naturalIdAnnotationInstance = JandexHelper.getSingleAnnotation( + annotations, + HibernateDotNames.NATURAL_ID + ); + SingularAttributeBinding.NaturalIdMutability naturalIdMutability; + if ( naturalIdAnnotationInstance != null ) { + naturalIdMutability = JandexHelper.getValue( + naturalIdAnnotationInstance, + "mutable", + Boolean.class + ) ? SingularAttributeBinding.NaturalIdMutability.MUTABLE : SingularAttributeBinding.NaturalIdMutability.IMMUTABLE; + } + else { + naturalIdMutability = SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; + } + final EmbeddableHierarchy hierarchy = EmbeddableHierarchy.createEmbeddableHierarchy( localBindingContext.locateClassByName( embeddableClassInfo.toString() ), attributeName, classAccessType, + naturalIdMutability, localBindingContext ); embeddedClasses.put( attributeName, hierarchy.getLeaf() ); @@ -570,14 +581,14 @@ private AttributeNature determineAttributeNature(Map { * * @return a set of {@code ConfiguredClassHierarchy}s. One for each "leaf" entity. */ - public static EmbeddableHierarchy createEmbeddableHierarchy(Class embeddableClass, String propertyName, AccessType accessType, AnnotationBindingContext context) { + public static EmbeddableHierarchy createEmbeddableHierarchy(Class embeddableClass, String propertyName, + AccessType accessType, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, AnnotationBindingContext context) { ClassInfo embeddableClassInfo = context.getClassInfo( embeddableClass.getName() ); if ( embeddableClassInfo == null ) { @@ -76,11 +82,12 @@ public static EmbeddableHierarchy createEmbeddableHierarchy(Class embeddableC ); } + + List classInfoList = new ArrayList(); - ClassInfo tmpClassInfo; Class clazz = embeddableClass; while ( clazz != null && !clazz.equals( Object.class ) ) { - tmpClassInfo = context.getIndex().getClassByName( DotName.createSimple( clazz.getName() ) ); + ClassInfo tmpClassInfo = context.getIndex().getClassByName( DotName.createSimple( clazz.getName() ) ); clazz = clazz.getSuperclass(); if ( tmpClassInfo == null ) { continue; @@ -92,6 +99,7 @@ public static EmbeddableHierarchy createEmbeddableHierarchy(Class embeddableC return new EmbeddableHierarchy( classInfoList, propertyName, + naturalIdMutability, context, accessType ); @@ -101,6 +109,7 @@ public static EmbeddableHierarchy createEmbeddableHierarchy(Class embeddableC private EmbeddableHierarchy( List classInfoList, String propertyName, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, AnnotationBindingContext context, AccessType defaultAccessType) { this.defaultAccessType = defaultAccessType; @@ -108,12 +117,11 @@ private EmbeddableHierarchy( // the resolved type for the top level class in the hierarchy context.resolveAllTypes( classInfoList.get( classInfoList.size() - 1 ).name().toString() ); - embeddables = new ArrayList(); + this.embeddables = new ArrayList(); ConfiguredClass parent = null; - EmbeddableClass embeddable; for ( ClassInfo info : classInfoList ) { - embeddable = new EmbeddableClass( - info, propertyName, parent, defaultAccessType, context + EmbeddableClass embeddable = new EmbeddableClass( + info, propertyName, parent, defaultAccessType,naturalIdMutability, context ); embeddables.add( embeddable ); parent = embeddable; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java index 85500d6be1..e8f2048dc0 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityClass.java @@ -57,6 +57,7 @@ import org.hibernate.annotations.OptimisticLockType; import org.hibernate.annotations.PolymorphismType; import org.hibernate.engine.OptimisticLockStyle; +import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContext; import org.hibernate.metamodel.internal.source.annotations.attribute.Column; import org.hibernate.metamodel.internal.source.annotations.attribute.FormulaValue; @@ -80,6 +81,7 @@ * @author Hardy Ferentschik */ public class EntityClass extends ConfiguredClass { + private static final String NATURAL_ID_CACHE_SUFFIX = "##NaturalId"; private final IdType idType; private final InheritanceType inheritanceType; @@ -98,6 +100,7 @@ public class EntityClass extends ConfiguredClass { private String whereClause; private String rowId; private Caching caching; + private Caching naturalIdCaching; private boolean isDynamicInsert; private boolean isDynamicUpdate; private boolean isSelectBeforeUpdate; @@ -204,6 +207,10 @@ public Caching getCaching() { return caching; } + public Caching getNaturalIdCaching(){ + return naturalIdCaching; + } + public TableSpecificationSource getPrimaryTableSource() { // todo : this is different from hbm which returns null if "!definesItsOwnTable()" if ( definesItsOwnTable() ) { @@ -484,6 +491,8 @@ private void processHibernateEntitySpecificAnnotations() { caching = determineCachingSettings(); + naturalIdCaching = determineNaturalIdCachingSettings(caching); + // see HHH-6397 isDynamicInsert = hibernateEntityAnnotation != null @@ -525,6 +534,28 @@ private void processHibernateEntitySpecificAnnotations() { this.customPersister = entityPersisterClass; } + private Caching determineNaturalIdCachingSettings(final Caching entityCache) { + final AnnotationInstance naturalIdCacheAnnotation = JandexHelper.getSingleAnnotation( + getClassInfo(), + HibernateDotNames.NATURAL_ID_CACHE + ); + if ( naturalIdCacheAnnotation == null ) { + return null; + } + final String region; + if ( naturalIdCacheAnnotation.value( "region" ) == null || StringHelper.isEmpty( + naturalIdCacheAnnotation.value( + "region" + ).asString() + ) ) { + region = entityCache == null ? getEntityName() + NATURAL_ID_CACHE_SUFFIX : entityCache.getRegion() + NATURAL_ID_CACHE_SUFFIX; + } + else { + region = naturalIdCacheAnnotation.value( "region" ).asString(); + } + return new Caching( region, null, false ); + } + private Caching determineCachingSettings() { final AnnotationInstance hibernateCacheAnnotation = JandexHelper.getSingleAnnotation( getClassInfo(), HibernateDotNames.CACHE diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/RootEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/RootEntitySourceImpl.java index 7690d4ec56..37da9878e2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/RootEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/RootEntitySourceImpl.java @@ -146,6 +146,11 @@ public Caching getCaching() { return getEntityClass().getCaching(); } + @Override + public Caching getNaturalIdCaching() { + return getEntityClass().getNaturalIdCaching(); + } + private class AggregatedCompositeIdentifierSourceImpl implements AggregatedCompositeIdentifierSource { private final ComponentAttributeSourceImpl componentAttributeSource; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/HibernateDotNames.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/HibernateDotNames.java index 314285f408..014cee65a8 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/HibernateDotNames.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/util/HibernateDotNames.java @@ -72,6 +72,7 @@ import org.hibernate.annotations.NamedQueries; import org.hibernate.annotations.NamedQuery; import org.hibernate.annotations.NaturalId; +import org.hibernate.annotations.NaturalIdCache; import org.hibernate.annotations.NotFound; import org.hibernate.annotations.OnDelete; import org.hibernate.annotations.OptimisticLock; @@ -156,6 +157,7 @@ public interface HibernateDotNames { DotName NAMED_QUERIES = DotName.createSimple( NamedQueries.class.getName() ); DotName NAMED_QUERY = DotName.createSimple( NamedQuery.class.getName() ); DotName NATURAL_ID = DotName.createSimple( NaturalId.class.getName() ); + DotName NATURAL_ID_CACHE = DotName.createSimple( NaturalIdCache.class.getName() ); DotName NOT_FOUND = DotName.createSimple( NotFound.class.getName() ); DotName ON_DELETE = DotName.createSimple( OnDelete.class.getName() ); DotName OPTIMISTIC_LOCK = DotName.createSimple( OptimisticLock.class.getName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractComponentAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractComponentAttributeSourceImpl.java index 1a17f56241..47686b009e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractComponentAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractComponentAttributeSourceImpl.java @@ -35,6 +35,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JaxbOneToOneElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbPropertyElement; import org.hibernate.internal.util.Value; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.AttributeSource; import org.hibernate.metamodel.spi.source.AttributeSourceContainer; import org.hibernate.metamodel.spi.source.ComponentAttributeSource; @@ -51,7 +52,7 @@ public abstract class AbstractComponentAttributeSourceImpl extends AbstractHbmSo private final ComponentSourceElement componentSourceElement; private final AttributeSourceContainer parentContainer; private final List subAttributeSources; - private final NaturalIdMutability naturalIdMutability; + private final SingularAttributeBinding.NaturalIdMutability naturalIdMutability; private final Value> componentClassReference; private final String logicalTableName; private final String path; @@ -61,7 +62,7 @@ protected AbstractComponentAttributeSourceImpl( ComponentSourceElement componentSourceElement, AttributeSourceContainer parentContainer, String logicalTableName, - NaturalIdMutability naturalIdMutability) { + SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { super( sourceMappingDocument ); this.componentSourceElement = componentSourceElement; this.parentContainer = parentContainer; @@ -212,7 +213,7 @@ public String getPropertyAccessorName() { } @Override - public NaturalIdMutability getNaturalIdMutability() { + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { return naturalIdMutability; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractEntitySourceImpl.java index e90f0c3a40..0f2cdea4ee 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractEntitySourceImpl.java @@ -48,6 +48,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JoinElementSource; import org.hibernate.internal.util.StringHelper; import org.hibernate.metamodel.spi.binding.CustomSQL; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.AttributeSource; import org.hibernate.metamodel.spi.source.ConstraintSource; import org.hibernate.metamodel.spi.source.EntitySource; @@ -55,7 +56,6 @@ import org.hibernate.metamodel.spi.source.LocalBindingContext; import org.hibernate.metamodel.spi.source.MetaAttributeSource; import org.hibernate.metamodel.spi.source.SecondaryTableSource; -import org.hibernate.metamodel.spi.source.SingularAttributeSource; import org.hibernate.metamodel.spi.source.SubclassEntitySource; /** @@ -109,7 +109,7 @@ protected List buildAttributeSources(List attr attributeSources, entityElement.getPropertyOrManyToOneOrOneToOne(), null, - SingularAttributeSource.NaturalIdMutability.NOT_NATURAL_ID + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID ); return attributeSources; } @@ -118,7 +118,7 @@ protected void processAttributes( List results, List attributeElements, String logicalTableName, - SingularAttributeSource.NaturalIdMutability naturalIdMutability) { + SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { for ( Object attributeElement : attributeElements ) { results.add( buildAttributeSource( attributeElement, logicalTableName, naturalIdMutability ) ); } @@ -127,7 +127,7 @@ protected void processAttributes( protected AttributeSource buildAttributeSource( Object attributeElement, String logicalTableName, - SingularAttributeSource.NaturalIdMutability naturalIdMutability) { + SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { if ( JaxbPropertyElement.class.isInstance( attributeElement ) ) { return new PropertyAttributeSourceImpl( sourceMappingDocument(), @@ -215,7 +215,7 @@ private Set buildSecondaryTables() { attributeSources, joinElement.getPropertyOrManyToOneOrComponent(), logicalTableName, - SingularAttributeSource.NaturalIdMutability.NOT_NATURAL_ID + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID ); } return secondaryTableSources; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractPluralAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractPluralAttributeSourceImpl.java index 19ce18e39c..0c5855632e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractPluralAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/AbstractPluralAttributeSourceImpl.java @@ -32,7 +32,6 @@ import org.hibernate.engine.FetchTiming; import org.hibernate.internal.jaxb.mapping.hbm.PluralAttributeElement; import org.hibernate.internal.util.StringHelper; -import org.hibernate.internal.util.Value; import org.hibernate.metamodel.spi.binding.Caching; import org.hibernate.metamodel.spi.binding.CustomSQL; import org.hibernate.metamodel.spi.source.AttributeSourceContainer; @@ -57,7 +56,7 @@ public abstract class AbstractPluralAttributeSourceImpl private final PluralAttributeKeySource keySource; private final PluralAttributeElementSource elementSource; - private final Value cachingHolder; + private final Caching caching; protected AbstractPluralAttributeSourceImpl( MappingDocument sourceMappingDocument, @@ -74,7 +73,10 @@ protected AbstractPluralAttributeSourceImpl( ); this.elementSource = interpretElementType(); - this.cachingHolder = Helper.createCachingHolder( pluralAttributeElement.getCache(), StringHelper.qualify( container().getPath(), getName() ) ); + this.caching = Helper.createCaching( + pluralAttributeElement.getCache(), + StringHelper.qualify( container().getPath(), getName() ) + ); this.typeInformation = new ExplicitHibernateTypeSource() { @Override @@ -170,7 +172,7 @@ public String getCollectionTableCheck() { @Override public Caching getCaching() { - return cachingHolder.getValue(); + return caching; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ComponentAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ComponentAttributeSourceImpl.java index 763cae6559..c6d8666cfb 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ComponentAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ComponentAttributeSourceImpl.java @@ -31,6 +31,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JaxbTuplizerElement; import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.AttributeSource; import org.hibernate.metamodel.spi.source.AttributeSourceContainer; import org.hibernate.metamodel.spi.source.RelationalValueSource; @@ -44,7 +45,7 @@ public ComponentAttributeSourceImpl( JaxbComponentElement componentElement, AttributeSourceContainer parentContainer, String logicalTableName, - NaturalIdMutability naturalIdMutability) { + SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { super( sourceMappingDocument, componentElement, parentContainer, logicalTableName, naturalIdMutability ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/Helper.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/Helper.java index 72c4ea02d9..189d320a80 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/Helper.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/Helper.java @@ -40,6 +40,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JaxbColumnElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbJoinedSubclassElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbMetaElement; +import org.hibernate.internal.jaxb.mapping.hbm.JaxbNaturalIdCacheElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbParamElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbSubclassElement; import org.hibernate.internal.jaxb.mapping.hbm.JaxbUnionSubclassElement; @@ -66,6 +67,7 @@ * @author Gail Badner */ public class Helper { + private static final String NATURAL_ID_CACHE_SUFFIX = "##NaturalId"; public static final ExplicitHibernateTypeSource TO_ONE_ATTRIBUTE_TYPE_SOURCE = new ExplicitHibernateTypeSource() { @Override public String getName() { @@ -126,20 +128,39 @@ public static String determineEntityName(EntityElement entityElement, String unq : qualifyIfNeeded( entityElement.getName(), unqualifiedClassPackage ); } - public static Value createCachingHolder(final JaxbCacheElement cacheElement, final String defaultRegionName) { + public static Caching createCaching(final JaxbCacheElement cacheElement, final String defaultRegionName) { + if ( cacheElement == null ) { + return null; + } + final String region = cacheElement.getRegion() != null ? cacheElement.getRegion() : defaultRegionName; + final AccessType accessType = AccessType.fromExternalName( cacheElement.getUsage() ); + final boolean cacheLazyProps = !"non-lazy".equals( cacheElement.getInclude() ); + return new Caching( region, accessType, cacheLazyProps ); + } + + public static Value createNaturalIdCachingHolder(final JaxbNaturalIdCacheElement cacheElement, final String entityName, final Caching entityCache) { return new Value( - new Value.DeferredInitializer() { - @Override - public Caching initialize() { - if ( cacheElement == null ) { - return null; + new Value.DeferredInitializer() { + @Override + public Caching initialize() { + if ( cacheElement == null ) { + return null; + } + final String region; + if ( StringHelper.isEmpty( cacheElement.getRegion() ) ) { + if ( entityCache != null ) { + region = entityCache.getRegion() + NATURAL_ID_CACHE_SUFFIX; + } + else { + region = entityName + NATURAL_ID_CACHE_SUFFIX; + } + } + else { + region = cacheElement.getRegion(); + } + return new Caching( region, null, false ); } - final String region = cacheElement.getRegion() != null ? cacheElement.getRegion() : defaultRegionName; - final AccessType accessType = AccessType.fromExternalName( cacheElement.getUsage() ); - final boolean cacheLazyProps = !"non-lazy".equals( cacheElement.getInclude() ); - return new Caching( region, accessType, cacheLazyProps ); } - } ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ManyToOneAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ManyToOneAttributeSourceImpl.java index 82d91016bb..8a7bba05c6 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ManyToOneAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/ManyToOneAttributeSourceImpl.java @@ -31,6 +31,7 @@ import org.hibernate.engine.spi.CascadeStyle; import org.hibernate.internal.jaxb.mapping.hbm.JaxbManyToOneElement; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.relational.Value; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.MappingException; @@ -46,14 +47,14 @@ */ class ManyToOneAttributeSourceImpl extends AbstractHbmSourceNode implements ToOneAttributeSource { private final JaxbManyToOneElement manyToOneElement; - private final NaturalIdMutability naturalIdMutability; + private final SingularAttributeBinding.NaturalIdMutability naturalIdMutability; private final List valueSources; ManyToOneAttributeSourceImpl( MappingDocument sourceMappingDocument, final JaxbManyToOneElement manyToOneElement, final String logicalTableName, - NaturalIdMutability naturalIdMutability) { + SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { super( sourceMappingDocument ); this.manyToOneElement = manyToOneElement; this.naturalIdMutability = naturalIdMutability; @@ -119,7 +120,7 @@ public boolean isLazy() { } @Override - public NaturalIdMutability getNaturalIdMutability() { + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { return naturalIdMutability; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/PropertyAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/PropertyAttributeSourceImpl.java index 5b8d70e988..8ce0cc5d5b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/PropertyAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/PropertyAttributeSourceImpl.java @@ -28,6 +28,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JaxbPropertyElement; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.MetaAttributeSource; import org.hibernate.metamodel.spi.source.RelationalValueSource; @@ -43,13 +44,13 @@ class PropertyAttributeSourceImpl extends AbstractHbmSourceNode implements Singu private final JaxbPropertyElement propertyElement; private final ExplicitHibernateTypeSource typeSource; private final List valueSources; - private final NaturalIdMutability naturalIdMutability; + private final SingularAttributeBinding.NaturalIdMutability naturalIdMutability; PropertyAttributeSourceImpl( MappingDocument sourceMappingDocument, final JaxbPropertyElement propertyElement, final String logicalTableName, - NaturalIdMutability naturalIdMutability) { + SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { super( sourceMappingDocument ); this.propertyElement = propertyElement; this.typeSource = new ExplicitHibernateTypeSource() { @@ -135,7 +136,7 @@ public boolean isLazy() { } @Override - public NaturalIdMutability getNaturalIdMutability() { + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { return naturalIdMutability; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/RootEntitySourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/RootEntitySourceImpl.java index 18fb35073b..b335116c9b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/RootEntitySourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/RootEntitySourceImpl.java @@ -43,6 +43,7 @@ import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.spi.binding.Caching; import org.hibernate.metamodel.spi.binding.IdGenerator; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.AggregatedCompositeIdentifierSource; import org.hibernate.metamodel.spi.source.AttributeSource; import org.hibernate.metamodel.spi.source.ComponentAttributeSource; @@ -64,14 +65,20 @@ */ public class RootEntitySourceImpl extends AbstractEntitySourceImpl implements RootEntitySource { private final TableSpecificationSource primaryTable; - private final Value cachingHolder; + private final Caching caching; + private final Value naturalIdCachingHolder; protected RootEntitySourceImpl( MappingDocument sourceMappingDocument, JaxbHibernateMapping.JaxbClass entityElement) { super( sourceMappingDocument, entityElement ); this.primaryTable = Helper.createTableSource( sourceMappingDocument(), entityElement, this ); - this.cachingHolder = Helper.createCachingHolder( entityElement().getCache(), getEntityName() ); + this.caching = Helper.createCaching( entityElement().getCache(), getEntityName() ); + this.naturalIdCachingHolder = Helper.createNaturalIdCachingHolder( + entityElement.getNaturalIdCache(), + getEntityName(), + caching + ); afterInstantiation(); } @@ -131,8 +138,8 @@ protected List buildAttributeSources(List attr naturalId.getPropertyOrManyToOneOrComponent(), null, naturalId.isMutable() - ? SingularAttributeSource.NaturalIdMutability.MUTABLE - : SingularAttributeSource.NaturalIdMutability.IMMUTABLE + ? SingularAttributeBinding.NaturalIdMutability.MUTABLE + : SingularAttributeBinding.NaturalIdMutability.IMMUTABLE ); } return super.buildAttributeSources( attributeSources ); @@ -179,7 +186,12 @@ public OptimisticLockStyle getOptimisticLockStyle() { @Override public Caching getCaching() { - return cachingHolder.getValue(); + return caching; + } + + @Override + public Caching getNaturalIdCaching() { + return naturalIdCachingHolder.getValue(); } @Override @@ -417,7 +429,7 @@ protected CompositeIdentifierComponentAttributeSourceImpl() { entityElement().getCompositeId(), RootEntitySourceImpl.this, null, - SingularAttributeSource.NaturalIdMutability.NOT_NATURAL_ID + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID ); } @@ -523,7 +535,7 @@ public List getAttributeSourcesMakingUpIdentifier() { final AttributeSource attributeSource = buildAttributeSource( attributeElement, null, - SingularAttributeSource.NaturalIdMutability.NOT_NATURAL_ID + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID ); if ( ! attributeSource.isSingular() ) { throw new HibernateException( "Only singular attributes are supported for composite identifiers" ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/SingularIdentifierAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/SingularIdentifierAttributeSourceImpl.java index fef1e3a8da..65cc331574 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/SingularIdentifierAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/SingularIdentifierAttributeSourceImpl.java @@ -28,7 +28,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JaxbHibernateMapping; import org.hibernate.mapping.PropertyGeneration; -import org.hibernate.metamodel.spi.source.LocalBindingContext; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.MetaAttributeSource; import org.hibernate.metamodel.spi.source.RelationalValueSource; @@ -142,8 +142,8 @@ public boolean isLazy() { } @Override - public NaturalIdMutability getNaturalIdMutability() { - return NaturalIdMutability.NOT_NATURAL_ID; + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { + return SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/TimestampAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/TimestampAttributeSourceImpl.java index f01e8b2055..15bd160e6d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/TimestampAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/TimestampAttributeSourceImpl.java @@ -29,6 +29,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JaxbHibernateMapping; import org.hibernate.internal.util.Value; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.MetaAttributeSource; import org.hibernate.metamodel.spi.source.RelationalValueSource; @@ -141,8 +142,8 @@ public boolean isLazy() { } @Override - public NaturalIdMutability getNaturalIdMutability() { - return NaturalIdMutability.NOT_NATURAL_ID; + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { + return SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/VersionAttributeSourceImpl.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/VersionAttributeSourceImpl.java index 76e4e7e6a8..296e12afdf 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/VersionAttributeSourceImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/hbm/VersionAttributeSourceImpl.java @@ -29,6 +29,7 @@ import org.hibernate.internal.jaxb.mapping.hbm.JaxbHibernateMapping; import org.hibernate.internal.util.Value; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource; import org.hibernate.metamodel.spi.source.MetaAttributeSource; import org.hibernate.metamodel.spi.source.RelationalValueSource; @@ -147,8 +148,8 @@ public boolean isLazy() { } @Override - public NaturalIdMutability getNaturalIdMutability() { - return NaturalIdMutability.NOT_NATURAL_ID; + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { + return SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractSingularAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractSingularAttributeBinding.java index 55b23569a7..2273728294 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractSingularAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AbstractSingularAttributeBinding.java @@ -36,6 +36,7 @@ public abstract class AbstractSingularAttributeBinding implements SingularAttributeBinding { private final boolean isLazy; + private final NaturalIdMutability naturalIdMutability; protected AbstractSingularAttributeBinding( AttributeBindingContainer container, @@ -43,9 +44,11 @@ protected AbstractSingularAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean isLazy, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext) { super( container, attribute, propertyAccessorName, includedInOptimisticLocking, metaAttributeContext ); this.isLazy = isLazy; + this.naturalIdMutability = naturalIdMutability; } protected static boolean hasNullableRelationalValueBinding(List relationalValueBindings) { @@ -67,5 +70,10 @@ public boolean isLazy() { return isLazy; } + @Override + public NaturalIdMutability getNaturalIdMutability() { + return naturalIdMutability; + } + protected abstract void collectRelationalValueBindings(List valueBindings); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java index 52c435f7c7..5ae26c5f5c 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/AttributeBindingContainer.java @@ -97,6 +97,7 @@ public BasicAttributeBinding makeBasicAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, PropertyGeneration generation); @@ -118,6 +119,7 @@ public CompositeAttributeBinding makeComponentAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext); /** @@ -139,6 +141,7 @@ public ManyToOneAttributeBinding makeManyToOneAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, SingularAttributeBinding referencedAttributeBinding, List valueBindings); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/BackRefAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/BackRefAttributeBinding.java index 730b1cf636..8267efafbf 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/BackRefAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/BackRefAttributeBinding.java @@ -33,9 +33,7 @@ /** * @author Gail Badner */ -public class BackRefAttributeBinding - extends BasicAttributeBinding - implements SingularNonAssociationAttributeBinding { +public class BackRefAttributeBinding extends BasicAttributeBinding { PluralAttributeBinding pluralAttributeBinding; @@ -50,6 +48,7 @@ public class BackRefAttributeBinding null, false, false, + NaturalIdMutability.NOT_NATURAL_ID, null, PropertyGeneration.NEVER ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/BasicAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/BasicAttributeBinding.java index e0d61686fc..66b4e30d5e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/BasicAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/BasicAttributeBinding.java @@ -58,6 +58,7 @@ public class BasicAttributeBinding String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, PropertyGeneration generation) { super( @@ -66,6 +67,7 @@ public class BasicAttributeBinding propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext ); this.relationalValueBindings = Collections.unmodifiableList( relationalValueBindings ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java index cc8d63fc0e..b0129c6bb7 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/CompositeAttributeBinding.java @@ -56,6 +56,7 @@ public CompositeAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, SingularAttribute parentReference) { this( @@ -64,6 +65,7 @@ public CompositeAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext, parentReference, null @@ -74,6 +76,7 @@ public CompositeAttributeBinding( AttributeBindingContainer container, SingularAttribute attribute, String propertyAccessorName, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, List subAttributeBindings) { this( @@ -82,6 +85,7 @@ public CompositeAttributeBinding( propertyAccessorName, false, false, + naturalIdMutability, metaAttributeContext, null, subAttributeBindings @@ -94,6 +98,7 @@ private CompositeAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, SingularAttribute parentReference, List subAttributeBindings) { @@ -103,6 +108,7 @@ private CompositeAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext ); @@ -211,6 +217,7 @@ public BasicAttributeBinding makeBasicAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, PropertyGeneration generation) { final BasicAttributeBinding binding = new BasicAttributeBinding( @@ -220,6 +227,7 @@ public BasicAttributeBinding makeBasicAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext, generation ); @@ -239,6 +247,7 @@ public CompositeAttributeBinding makeComponentAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext) { final CompositeAttributeBinding binding = new CompositeAttributeBinding( this, @@ -246,6 +255,7 @@ public CompositeAttributeBinding makeComponentAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext, parentReferenceAttribute ); @@ -259,6 +269,7 @@ public ManyToOneAttributeBinding makeManyToOneAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, SingularAttributeBinding referencedAttributeBinding, List valueBindings) { @@ -268,6 +279,7 @@ public ManyToOneAttributeBinding makeManyToOneAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext, referencedAttributeBinding, valueBindings diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java index 748565f90c..3041ad4c6e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/EntityBinding.java @@ -490,6 +490,7 @@ public BasicAttributeBinding makeBasicAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, PropertyGeneration generation) { final BasicAttributeBinding binding = new BasicAttributeBinding( @@ -499,6 +500,7 @@ public BasicAttributeBinding makeBasicAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext, generation ); @@ -513,6 +515,7 @@ public CompositeAttributeBinding makeComponentAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext) { final CompositeAttributeBinding binding = new CompositeAttributeBinding( this, @@ -520,6 +523,7 @@ public CompositeAttributeBinding makeComponentAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext, parentReferenceAttribute ); @@ -540,6 +544,7 @@ public CompositeAttributeBinding makeVirtualComponentAttributeBinding( this, syntheticAttribute, PropertyAccessorFactory.EMBEDDED_ACCESSOR_NAME, + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID, metaAttributeContext, subAttributeBindings ); @@ -570,6 +575,7 @@ public ManyToOneAttributeBinding makeManyToOneAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + SingularAttributeBinding.NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, SingularAttributeBinding referencedAttributeBinding, List valueBindings) { @@ -579,6 +585,7 @@ public ManyToOneAttributeBinding makeManyToOneAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext, referencedAttributeBinding, valueBindings diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/HierarchyDetails.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/HierarchyDetails.java index 1272acca04..8c303b2df3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/HierarchyDetails.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/HierarchyDetails.java @@ -42,6 +42,7 @@ public class HierarchyDetails { private EntityVersion entityVersion; private Caching caching; + private Caching naturalIdCaching; private boolean explicitPolymorphism; @@ -106,6 +107,14 @@ public void setCaching(Caching caching) { this.caching = caching; } + public Caching getNaturalIdCaching() { + return naturalIdCaching; + } + + public void setNaturalIdCaching(Caching naturalIdCaching) { + this.naturalIdCaching = naturalIdCaching; + } + public boolean isExplicitPolymorphism() { return explicitPolymorphism; } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ManyToOneAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ManyToOneAttributeBinding.java index da8dcbdaa1..9b900c561e 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ManyToOneAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/ManyToOneAttributeBinding.java @@ -58,6 +58,7 @@ public ManyToOneAttributeBinding( String propertyAccessorName, boolean includedInOptimisticLocking, boolean lazy, + NaturalIdMutability naturalIdMutability, MetaAttributeContext metaAttributeContext, SingularAttributeBinding referencedAttributeBinding, List relationalValueBindings) { @@ -67,6 +68,7 @@ public ManyToOneAttributeBinding( propertyAccessorName, includedInOptimisticLocking, lazy, + naturalIdMutability, metaAttributeContext ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/SingularAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/SingularAttributeBinding.java index e92c55d11f..5ddceba93d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/SingularAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/SingularAttributeBinding.java @@ -53,4 +53,18 @@ public interface SingularAttributeBinding extends AttributeBinding { * @return {@code true} indicates that all values allow {@code null}; {@code false} indicates one or more do not */ public boolean isNullable(); + + /** + * Convenience method to determine if this attribute is an natural id and if it is, then returns its mutability. + * + * @return The {@link NaturalIdMutability} linked with this attribute, + * {@code NaturalIdMutability#NOT_NATURAL_ID} indicates this is NOT a natural id attribute. + */ + public NaturalIdMutability getNaturalIdMutability(); + + public enum NaturalIdMutability { + MUTABLE, + IMMUTABLE, + NOT_NATURAL_ID + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/RootEntitySource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/RootEntitySource.java index b565a39248..13f0a9a407 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/RootEntitySource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/RootEntitySource.java @@ -114,4 +114,11 @@ public interface RootEntitySource extends EntitySource { * @return The caching configuration. */ public Caching getCaching(); + + /** + * Obtain the natural id caching configuration for this entity. + * + * @return The natural id caching configuration. + */ + public Caching getNaturalIdCaching(); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SingularAttributeSource.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SingularAttributeSource.java index 8ea0c6d9b9..73d0554617 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SingularAttributeSource.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/source/SingularAttributeSource.java @@ -24,6 +24,7 @@ package org.hibernate.metamodel.spi.source; import org.hibernate.mapping.PropertyGeneration; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; /** * Source-agnostic description of information needed to bind a singular attribute. @@ -65,11 +66,6 @@ public interface SingularAttributeSource extends AttributeSource, RelationalValu * * @return The mutability, see enum for meanings */ - public NaturalIdMutability getNaturalIdMutability(); + public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability(); - public static enum NaturalIdMutability { - MUTABLE, - IMMUTABLE, - NOT_NATURAL_ID - } } diff --git a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java index 87b86586ba..851aa1161b 100644 --- a/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java +++ b/hibernate-core/src/main/java/org/hibernate/tuple/entity/EntityMetamodel.java @@ -447,15 +447,15 @@ public EntityMetamodel(EntityBinding entityBinding, SessionFactoryImplementor se else { properties[i] = PropertyFactory.buildStandardProperty( attributeBinding, instrumentationMetadata.isInstrumented() ); } - - // TODO: fix when natural IDs are added (HHH-6354) - //if ( attributeBinding.isNaturalIdentifier() ) { - // naturalIdNumbers.add( i ); - // if ( attributeBinding.isUpdateable() ) { - // foundUpdateableNaturalIdProperty = true; - // } - //} - + if ( SingularAttributeBinding.class.isInstance( attributeBinding ) ){ + SingularAttributeBinding singularAttributeBinding = SingularAttributeBinding.class.cast( attributeBinding ); + if(singularAttributeBinding.getNaturalIdMutability() == SingularAttributeBinding.NaturalIdMutability.MUTABLE){ + naturalIdNumbers.add( i ); + foundUpdateableNaturalIdProperty = true; + } else if(singularAttributeBinding.getNaturalIdMutability() == SingularAttributeBinding.NaturalIdMutability.IMMUTABLE){ + naturalIdNumbers.add( i ); + } + } if ( "id".equals( attributeBinding.getAttribute().getName() ) ) { foundNonIdentifierPropertyNamedId = true; } @@ -508,7 +508,7 @@ public EntityMetamodel(EntityBinding entityBinding, SessionFactoryImplementor se i++; } - if (naturalIdNumbers.size()==0) { + if (naturalIdNumbers.isEmpty()) { naturalIdPropertyNumbers = null; hasImmutableNaturalId = false; hasCacheableNaturalId = false; @@ -516,7 +516,7 @@ public EntityMetamodel(EntityBinding entityBinding, SessionFactoryImplementor se else { naturalIdPropertyNumbers = ArrayHelper.toIntArray(naturalIdNumbers); hasImmutableNaturalId = !foundUpdateableNaturalIdProperty; - hasCacheableNaturalId = false; //See previous TODO and HHH-6354 + hasCacheableNaturalId = entityBinding.getHierarchyDetails().getNaturalIdCaching() != null; } hasInsertGeneratedValues = foundInsertGeneratedValue; diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/util/BaseAnnotationIndexTestCase.java b/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/util/BaseAnnotationIndexTestCase.java index 566c8773e0..d036f2e508 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/util/BaseAnnotationIndexTestCase.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/util/BaseAnnotationIndexTestCase.java @@ -36,6 +36,7 @@ import org.hibernate.metamodel.internal.source.annotations.AnnotationBindingContextImpl; import org.hibernate.metamodel.internal.source.annotations.EntityHierarchyBuilder; import org.hibernate.metamodel.internal.source.annotations.entity.EmbeddableHierarchy; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import org.hibernate.metamodel.spi.source.EntityHierarchy; import org.hibernate.service.ServiceRegistryBuilder; import org.hibernate.service.classloading.spi.ClassLoaderService; @@ -66,13 +67,14 @@ public Set createEntityHierarchies(Class... clazz) { return EntityHierarchyBuilder.createEntityHierarchies( context ); } - public EmbeddableHierarchy createEmbeddableHierarchy(AccessType accessType, Class... configuredClasses) { + public EmbeddableHierarchy createEmbeddableHierarchy(AccessType accessType,SingularAttributeBinding.NaturalIdMutability naturalIdMutability, Class... configuredClasses) { Index index = JandexHelper.indexForClass( meta.getServiceRegistry().getService( ClassLoaderService.class ), configuredClasses ); AnnotationBindingContext context = new AnnotationBindingContextImpl( meta, index ); - return EmbeddableHierarchy.createEmbeddableHierarchy( configuredClasses[0], "", accessType, context ); + return EmbeddableHierarchy.createEmbeddableHierarchy( configuredClasses[0], "", accessType, + naturalIdMutability, context ); } } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/util/EmbeddableHierarchyTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/util/EmbeddableHierarchyTest.java index d27146d2b1..efac81d248 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/util/EmbeddableHierarchyTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/internal/source/annotations/util/EmbeddableHierarchyTest.java @@ -38,6 +38,7 @@ import org.hibernate.AssertionFailure; import org.hibernate.metamodel.internal.source.annotations.entity.EmbeddableClass; import org.hibernate.metamodel.internal.source.annotations.entity.EmbeddableHierarchy; +import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; import static junit.framework.Assert.assertEquals; import static junit.framework.Assert.assertNotNull; @@ -65,7 +66,7 @@ class C extends B { } EmbeddableHierarchy hierarchy = createEmbeddableHierarchy( - AccessType.FIELD, + AccessType.FIELD, SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID, C.class, A.class, B.class @@ -86,7 +87,8 @@ public void testEmbeddableHierarchyWithNotAnnotatedEntity() { class NonAnnotatedEmbeddable { } - createEmbeddableHierarchy( AccessType.FIELD, NonAnnotatedEmbeddable.class ); + createEmbeddableHierarchy( AccessType.FIELD, + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID, NonAnnotatedEmbeddable.class ); } @Entity diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/SimpleValueBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/SimpleValueBindingTests.java index 2f810be772..fe0fa20f37 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/SimpleValueBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/spi/binding/SimpleValueBindingTests.java @@ -86,6 +86,7 @@ public void testBasicMiddleOutBuilding() { "property", true, false, + SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID, null, PropertyGeneration.NEVER );