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 ffe33019ee..adbd462576 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 @@ -171,21 +171,22 @@ public class Binder { private final MetadataImplementor metadata; private final IdentifierGeneratorFactory identifierGeneratorFactory; private final ObjectNameNormalizer nameNormalizer; - private final HashMap< String, EntitySource > entitySourcesByName = new HashMap< String, EntitySource >(); - private final HashMap< RootEntitySource, EntityHierarchy > entityHierarchiesByRootEntitySource = - new HashMap< RootEntitySource, EntityHierarchy >(); - private final HashMap< String, AttributeSource > attributeSourcesByName = new HashMap< String, AttributeSource >(); - private final LinkedList< LocalBindingContext > bindingContexts = new LinkedList< LocalBindingContext >(); - private final LinkedList< InheritanceType > inheritanceTypes = new LinkedList< InheritanceType >(); + private final HashMap entitySourcesByName = new HashMap(); + private final HashMap entityHierarchiesByRootEntitySource = + new HashMap(); + private final HashMap attributeSourcesByName = new HashMap(); + private final LinkedList bindingContexts = new LinkedList(); + private final LinkedList inheritanceTypes = new LinkedList(); - private final LinkedList< EntityMode > entityModes = new LinkedList< EntityMode >(); + private final LinkedList entityModes = new LinkedList(); private final HibernateTypeHelper typeHelper; // todo: refactor helper and remove redundant methods in this class public Binder( final MetadataImplementor metadata, final IdentifierGeneratorFactory identifierGeneratorFactory ) { this.metadata = metadata; this.identifierGeneratorFactory = identifierGeneratorFactory; - nameNormalizer = new ObjectNameNormalizer() { + this.typeHelper = new HibernateTypeHelper( this, metadata ); + this.nameNormalizer = new ObjectNameNormalizer() { @Override protected NamingStrategy getNamingStrategy() { @@ -197,13 +198,12 @@ public class Binder { return metadata.isGloballyQuotedIdentifiers(); } }; - typeHelper = new HibernateTypeHelper( this, metadata ); } private AttributeBinding attributeBinding( final String entityName, final String attributeName ) { // Check if binding has already been created - EntityBinding entityBinding = entityBinding( entityName ); - AttributeSource attributeSource = attributeSourcesByName.get( attributeSourcesByNameKey( entityName, attributeName ) ); + final EntityBinding entityBinding = entityBinding( entityName ); + final AttributeSource attributeSource = attributeSourcesByName.get( attributeSourcesByNameKey( entityName, attributeName ) ); bindAttribute( entityBinding, attributeSource ); return entityBinding.locateAttributeBinding( attributeName ); } @@ -250,13 +250,13 @@ public class Binder { case MANY_TO_ONE: return bindManyToOneAttribute( attributeBindingContainer, - (ToOneAttributeSource) attributeSource, + ToOneAttributeSource.class.cast( attributeSource ), attribute ); case COMPONENT: return bindComponentAttribute( attributeBindingContainer, - (ComponentAttributeSource) attributeSource, + ComponentAttributeSource.class.cast( attributeSource ), attribute ); default: @@ -303,16 +303,14 @@ public class Binder { final AttributeBindingContainer attributeBindingContainer, final ComponentAttributeSource attributeSource, SingularAttribute attribute ) { - Composite composite; + final Composite composite; if ( attribute == null ) { - composite = - new Composite( + composite = new Composite( attributeSource.getPath(), attributeSource.getClassName(), attributeSource.getClassReference(), null ); - attribute = - attributeBindingContainer.getAttributeContainer().createCompositeAttribute( + attribute = attributeBindingContainer.getAttributeContainer().createCompositeAttribute( attributeSource.getName(), composite ); } else { @@ -325,6 +323,7 @@ public class Binder { } else { referencingAttribute = composite.createSingularAttribute( attributeSource.getParentReferenceAttributeName() ); } + final SingularAttributeBinding.NaturalIdMutability naturalIdMutability = attributeSource.getNaturalIdMutability(); final CompositeAttributeBinding attributeBinding = attributeBindingContainer.makeComponentAttributeBinding( attribute, @@ -332,7 +331,7 @@ public class Binder { propertyAccessorName( attributeSource ), attributeSource.isIncludedInOptimisticLocking(), attributeSource.isLazy(), - attributeSource.getNaturalIdMutability(), + naturalIdMutability, createMetaAttributeContext( attributeBindingContainer, attributeSource ) ); bindAttributes( attributeBinding, attributeSource ); return attributeBinding; @@ -346,7 +345,7 @@ public class Binder { attribute = createSingularAttribute( attributeBindingContainer, attributeSource ); } // TODO: figure out which table is used (could be secondary table...) - TableSpecification table = attributeBindingContainer.seekEntityBinding().getPrimaryTable(); + final TableSpecification table = attributeBindingContainer.seekEntityBinding().getPrimaryTable(); final List< RelationalValueBinding > relationalValueBindings = bindValues( attributeBindingContainer, attributeSource, attribute, table ); @@ -936,7 +935,6 @@ public class Binder { bindingContexts.peek().getMappingDefaults().getDiscriminatorColumnName(), false, false, - false, false ); } else { value = table.locateOrCreateDerivedValue( ( ( DerivedValueSource ) valueSource ).getExpression() ); @@ -995,7 +993,6 @@ public class Binder { bindingContexts.peek().getMappingDefaults().getDiscriminatorColumnName(), false, false, - false, false ); } @@ -1459,7 +1456,7 @@ public class Binder { private void bindUniqueConstraints( final EntityBinding entityBinding, final EntitySource entitySource ) { for ( final ConstraintSource constraintSource : entitySource.getConstraints() ) { - if ( constraintSource instanceof UniqueConstraintSource ) { + if ( UniqueConstraintSource.class.isInstance( constraintSource ) ) { final TableSpecification table = entityBinding.locateTable( constraintSource.getTableName() ); final String constraintName = constraintSource.name(); if ( constraintName == null ) { @@ -1484,14 +1481,17 @@ public class Binder { ) ? SingularAttributeSource.class.cast( valueSourceContainer ).getNaturalIdMutability() : SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; final boolean isNaturalId = naturalIdMutability != SingularAttributeBinding.NaturalIdMutability.NOT_NATURAL_ID; - final boolean isImmutable = isNaturalId && (naturalIdMutability == SingularAttributeBinding.NaturalIdMutability.IMMUTABLE); + final boolean isImmutableNaturalId = isNaturalId && (naturalIdMutability == SingularAttributeBinding.NaturalIdMutability.IMMUTABLE); + if ( valueSourceContainer.relationalValueSources().isEmpty() ) { final String columnName = quotedIdentifier( bindingContexts.peek().getNamingStrategy().propertyToColumnName( attribute.getName() ) ); final Column column = defaultTable.locateOrCreateColumn( columnName ); column.setNullable( !isNaturalId && valueSourceContainer.areValuesNullableByDefault() ); - column.setUnique( isNaturalId ); - valueBindings.add( new RelationalValueBinding( column, true, !isImmutable ) ); + if(isNaturalId){ + addUniqueConstraintForNaturalIdColumn( defaultTable, column ); + } + valueBindings.add( new RelationalValueBinding( column, true, !isImmutableNaturalId ) ); } else { final String name = attribute.getName(); for ( final RelationalValueSource valueSource : valueSourceContainer.relationalValueSources() ) { @@ -1509,15 +1509,11 @@ public class Binder { toBoolean( columnSource.isIncludedInUpdate(), valueSourceContainer.areValuesIncludedInUpdateByDefault() ); - - valueBindings.add( new RelationalValueBinding( createColumn( - table, - columnSource, - name, - isNaturalId, - isNaturalId, - valueSourceContainer.areValuesNullableByDefault(), - true ), isIncludedInInsert, !isImmutable && isIncludedInUpdate ) ); + Column column = createColumn( table, columnSource, name, isNaturalId, valueSourceContainer.areValuesNullableByDefault(), true ); + if(isNaturalId){ + addUniqueConstraintForNaturalIdColumn( table, column ); + } + valueBindings.add( new RelationalValueBinding( column, isIncludedInInsert, !isImmutableNaturalId && isIncludedInUpdate ) ); } else { final DerivedValue derivedValue = table.locateOrCreateDerivedValue( ( ( DerivedValueSource ) valueSource ).getExpression() ); @@ -1528,6 +1524,11 @@ public class Binder { return valueBindings; } + private void addUniqueConstraintForNaturalIdColumn(final TableSpecification table, final Column column) { + final UniqueKey uniqueKey = table.getOrCreateUniqueKey( "natural_id_unique_key_" ); + uniqueKey.addColumn( column ); + } + private void bindVersion( final EntityBinding rootEntityBinding, final VersionAttributeSource versionAttributeSource ) { if ( versionAttributeSource == null ) { return; @@ -1575,7 +1576,6 @@ public class Binder { final ColumnSource columnSource, final String defaultName, final boolean forceNotNull, - final boolean forceUnique, final boolean isNullableByDefault, final boolean isDefaultAttributeName ) { if ( columnSource.getName() == null && defaultName == null ) { @@ -1608,7 +1608,7 @@ public class Binder { column.setJdbcDataType( columnSource.getDatatype() ); column.setReadFragment( columnSource.getReadFragment() ); column.setWriteFragment( columnSource.getWriteFragment() ); - column.setUnique( forceUnique || columnSource.isUnique() ); + column.setUnique( columnSource.isUnique() ); column.setCheckCondition( columnSource.getCheckCondition() ); column.setComment( columnSource.getComment() ); return column; 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 f83fe5f552..da94eac655 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 @@ -85,7 +85,7 @@ public abstract class MappedAttribute implements Comparable { /** * Is this property a natural id property and what's the mutability it is. */ - private final SingularAttributeBinding.NaturalIdMutability naturalIdMutability; + private SingularAttributeBinding.NaturalIdMutability naturalIdMutability; /** * Whether a change of the property's value triggers a version increment of the entity (in case of optimistic @@ -164,6 +164,10 @@ public abstract class MappedAttribute implements Comparable { return naturalIdMutability; } + public void setNaturalIdMutability(SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { + this.naturalIdMutability = naturalIdMutability; + } + public AttributeNature getAttributeNature() { return attributeNature; } @@ -281,6 +285,8 @@ public abstract class MappedAttribute implements Comparable { } return checkCondition; } + + } 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 3908fbf9c1..1d56e65aaa 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 @@ -122,9 +122,11 @@ public class ComponentAttributeSourceImpl implements ComponentAttributeSource { if ( attributeOverrides.containsKey( tmp ) ) { attributeOverride = attributeOverrides.get( tmp ); } + attribute.setNaturalIdMutability( embeddableClass.getNaturalIdMutability() ); attributeList.add( new SingularAttributeSourceImpl( attribute, attributeOverride ) ); } for ( EmbeddableClass embeddable : embeddableClass.getEmbeddedClasses().values() ) { + embeddable.setNaturalIdMutability( embeddableClass.getNaturalIdMutability() ); attributeList.add( new ComponentAttributeSourceImpl( embeddable, @@ -134,6 +136,7 @@ public class ComponentAttributeSourceImpl implements ComponentAttributeSource { ); } for ( AssociationAttribute associationAttribute : embeddableClass.getAssociationAttributes() ) { + associationAttribute.setNaturalIdMutability( embeddableClass.getNaturalIdMutability() ); attributeList.add( new ToOneAttributeSourceImpl( associationAttribute ) ); } return Collections.unmodifiableList( attributeList ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EmbeddableClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EmbeddableClass.java index eded5f7cb7..2897396842 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EmbeddableClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EmbeddableClass.java @@ -41,7 +41,7 @@ import org.hibernate.metamodel.spi.binding.SingularAttributeBinding; public class EmbeddableClass extends ConfiguredClass { private final String embeddedAttributeName; private final String parentReferencingAttributeName; - private final SingularAttributeBinding.NaturalIdMutability naturalIdMutability; + private SingularAttributeBinding.NaturalIdMutability naturalIdMutability; public EmbeddableClass( ClassInfo classInfo, @@ -75,6 +75,10 @@ public class EmbeddableClass extends ConfiguredClass { public SingularAttributeBinding.NaturalIdMutability getNaturalIdMutability() { return naturalIdMutability; } + + public void setNaturalIdMutability(SingularAttributeBinding.NaturalIdMutability naturalIdMutability) { + this.naturalIdMutability = naturalIdMutability; + } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java index e79061d8d9..3719fc7f28 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/internal/source/annotations/entity/EntityBindingContext.java @@ -67,8 +67,7 @@ public class EntityBindingContext implements LocalBindingContext, AnnotationBind public EntityBindingContext(AnnotationBindingContext contextDelegate, ConfiguredClass source) { this.contextDelegate = contextDelegate; this.origin = new Origin( SourceType.ANNOTATION, source.getName() ); - - localIdentifierGeneratorDefinitionMap = processLocalIdentifierGeneratorDefinitions( source.getClassInfo() ); + this.localIdentifierGeneratorDefinitionMap = processLocalIdentifierGeneratorDefinitions( source.getClassInfo() ); } private Map processLocalIdentifierGeneratorDefinitions(final ClassInfo classInfo) { @@ -217,7 +216,7 @@ public class EntityBindingContext implements LocalBindingContext, AnnotationBind public IdGenerator findIdGenerator(String name) { IdGenerator definition = localIdentifierGeneratorDefinitionMap.get( name ); if ( definition == null ) { - contextDelegate.findIdGenerator( name ); + definition= contextDelegate.findIdGenerator( name ); } return definition; } 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 e8f2048dc0..db80406759 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 @@ -131,17 +131,13 @@ public class EntityClass extends ConfiguredClass { super( classInfo, hierarchyAccessType, parent, context ); this.inheritanceType = inheritanceType; this.idType = determineIdType(); - boolean hasOwnTable = definesItsOwnTable(); + + final boolean hasOwnTable = definesItsOwnTable(); + this.explicitEntityName = determineExplicitEntityName(); this.constraintSources = new HashSet(); - - if ( hasOwnTable ) { - this.primaryTableSource = createPrimaryTableSource(); - } - else { - this.primaryTableSource = null; - } + this.primaryTableSource = hasOwnTable ? createPrimaryTableSource() : null; this.secondaryTableSources = createSecondaryTableSources(); this.customLoaderQueryName = determineCustomLoader(); @@ -213,12 +209,7 @@ public class EntityClass extends ConfiguredClass { public TableSpecificationSource getPrimaryTableSource() { // todo : this is different from hbm which returns null if "!definesItsOwnTable()" - if ( definesItsOwnTable() ) { - return primaryTableSource; - } - else { - return ( (EntityClass) getParent() ).getPrimaryTableSource(); - } + return definesItsOwnTable() ? primaryTableSource : ( (EntityClass) getParent() ).getPrimaryTableSource(); } public Set getSecondaryTableSources() { @@ -669,16 +660,16 @@ public class EntityClass extends ConfiguredClass { } private void createUniqueConstraints(AnnotationInstance tableAnnotation, String tableName) { - AnnotationValue value = tableAnnotation.value( "uniqueConstraints" ); + final AnnotationValue value = tableAnnotation.value( "uniqueConstraints" ); if ( value == null ) { return; } - AnnotationInstance[] uniqueConstraints = value.asNestedArray(); - for ( AnnotationInstance unique : uniqueConstraints ) { - String name = unique.value( "name" ) == null ? null : unique.value( "name" ).asString(); - String[] columnNames = unique.value( "columnNames" ).asStringArray(); - UniqueConstraintSourceImpl uniqueConstraintSource = + final AnnotationInstance[] uniqueConstraints = value.asNestedArray(); + for ( final AnnotationInstance unique : uniqueConstraints ) { + final String name = unique.value( "name" ) == null ? null : unique.value( "name" ).asString(); + final String[] columnNames = unique.value( "columnNames" ).asStringArray(); + final UniqueConstraintSourceImpl uniqueConstraintSource = new UniqueConstraintSourceImpl( name, tableName, Arrays.asList( columnNames ) ); @@ -827,12 +818,7 @@ public class EntityClass extends ConfiguredClass { || hibernateProxyAnnotation.value( "lazy" ).asBoolean(); if ( isLazy ) { final AnnotationValue proxyClassValue = hibernateProxyAnnotation.value( "proxyClass" ); - if ( proxyClassValue == null ) { - proxy = getName(); - } - else { - proxy = proxyClassValue.asString(); - } + proxy = proxyClassValue == null? getName() : proxyClassValue.asString(); } else { proxy = null; 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 b0129c6bb7..bb46e1c7ee 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 @@ -193,12 +193,12 @@ public class CompositeAttributeBinding @Override public AttributeBinding locateAttributeBinding(List values) { - for(AttributeBinding attributeBinding : attributeBindingMap.values()) { - if(!(attributeBinding instanceof BasicAttributeBinding)) { + for ( final AttributeBinding attributeBinding : attributeBindingMap.values() ) { + if ( !BasicAttributeBinding.class.isInstance( attributeBinding ) ) { continue; } - BasicAttributeBinding basicAttributeBinding = (BasicAttributeBinding) attributeBinding; - if(basicAttributeBinding.getRelationalValueBindings().equals( values )) { + final BasicAttributeBinding basicAttributeBinding = (BasicAttributeBinding) attributeBinding; + if ( basicAttributeBinding.getRelationalValueBindings().equals( values ) ) { return attributeBinding; } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/RelationalValueBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/RelationalValueBinding.java index d0ac4f7a36..7f244c613a 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/RelationalValueBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/spi/binding/RelationalValueBinding.java @@ -43,7 +43,7 @@ public class RelationalValueBinding { private final boolean isDerived; private final boolean isNullable; - public RelationalValueBinding(DerivedValue value) { + public RelationalValueBinding(final DerivedValue value) { this.value = value; this.includeInInsert = false; this.includeInUpdate = false; @@ -51,7 +51,7 @@ public class RelationalValueBinding { this.isNullable = true; } - public RelationalValueBinding(Column value, boolean includeInInsert, boolean includeInUpdate) { + public RelationalValueBinding(final Column value, final boolean includeInInsert, final boolean includeInUpdate) { this.value = value; this.includeInInsert = includeInInsert; this.includeInUpdate = includeInUpdate; diff --git a/hibernate-core/src/test/java/org/hibernate/test/naturalid/immutableentity/Building.java b/hibernate-core/src/test/java/org/hibernate/test/naturalid/immutableentity/Building.java index e5cc8880a4..d9f6760a26 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/naturalid/immutableentity/Building.java +++ b/hibernate-core/src/test/java/org/hibernate/test/naturalid/immutableentity/Building.java @@ -44,7 +44,7 @@ public class Building { private Integer id; private String name; - + @NaturalId private String address; @NaturalId @@ -138,5 +138,5 @@ public class Building { return "Building [id=" + id + ", name=" + name + ", address=" + address + ", city=" + city + ", state=" + state + "]"; } - + }