diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ColumnValues.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ColumnValues.java index ecf966afd6..ad015005b1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ColumnValues.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ColumnValues.java @@ -45,14 +45,14 @@ public final class ColumnValues { private int precision = 0; private int scale = 0; - public ColumnValues(AnnotationInstance columnAnnotation) { + public ColumnValues(AnnotationInstance columnAnnotation, boolean isId) { if ( columnAnnotation != null && !JPADotNames.COLUMN.equals( columnAnnotation.name() ) ) { throw new AssertionFailure( "A @Column annotation needs to be passed to the constructor" ); } - applyColumnValues( columnAnnotation ); + applyColumnValues( columnAnnotation, isId ); } - private void applyColumnValues(AnnotationInstance columnAnnotation) { + private void applyColumnValues(AnnotationInstance columnAnnotation, boolean isId) { if ( columnAnnotation == null ) { return; } @@ -62,14 +62,26 @@ public final class ColumnValues { this.name = nameValue.asString(); } - AnnotationValue uniqueValue = columnAnnotation.value( "unique" ); - if ( uniqueValue != null ) { - this.unique = nameValue.asBoolean(); + // id attribute must be unique + if ( isId ) { + this.unique = true; + } + else { + AnnotationValue uniqueValue = columnAnnotation.value( "unique" ); + if ( uniqueValue != null ) { + this.unique = nameValue.asBoolean(); + } } - AnnotationValue nullableValue = columnAnnotation.value( "nullable" ); - if ( nullableValue != null ) { - this.nullable = nullableValue.asBoolean(); + // id attribute cannot be nullable + if ( isId ) { + this.nullable = false; + } + else { + AnnotationValue nullableValue = columnAnnotation.value( "nullable" ); + if ( nullableValue != null ) { + this.nullable = nullableValue.asBoolean(); + } } AnnotationValue insertableValue = columnAnnotation.value( "insertable" ); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java index a8e56834ef..cb344e63d5 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java @@ -68,6 +68,8 @@ public class EntityBinder { if ( configuredClass.isRoot() ) { bindId( entityBinding ); } + bindAttributes( entityBinding ); + meta.addEntity( entityBinding ); } @@ -164,7 +166,6 @@ public class EntityBinder { typeDescriptor.setTypeName( idAttribute.getType().getName() ); domainState.typeDescriptor = typeDescriptor; domainState.attribute = entityBinding.getEntity().getOrCreateSingularAttribute( idAttribute.getName() ); - idBinding.initialize( domainState ); AttributeColumnRelationalState columnRelationsState = new AttributeColumnRelationalState( idAttribute, meta ); @@ -173,6 +174,32 @@ public class EntityBinder { idBinding.initializeSimpleTupleValue( relationalState ); } + private void bindAttributes(EntityBinding entityBinding) { + for ( MappedAttribute mappedAttribute : configuredClass.getMappedAttributes() ) { + if ( mappedAttribute.isId() ) { + continue; + } + + String attributeName = mappedAttribute.getName(); + entityBinding.getEntity().getOrCreateSingularAttribute( attributeName ); + SimpleAttributeBinding simpleBinding = entityBinding.makeSimpleAttributeBinding( attributeName ); + + AnnotationSimpleAttributeDomainState domainState = new AnnotationSimpleAttributeDomainState(); + HibernateTypeDescriptor typeDescriptor = new HibernateTypeDescriptor(); + typeDescriptor.setTypeName( mappedAttribute.getType().getName() ); + domainState.typeDescriptor = typeDescriptor; + domainState.attribute = entityBinding.getEntity().getOrCreateSingularAttribute( attributeName ); + simpleBinding.initialize( domainState ); + + AttributeColumnRelationalState columnRelationsState = new AttributeColumnRelationalState( + mappedAttribute, meta + ); + AnnotationSimpleAttributeRelationalState relationalState = new AnnotationSimpleAttributeRelationalState(); + relationalState.valueStates.add( columnRelationsState ); + simpleBinding.initializeSimpleTupleValue( relationalState ); + } + } + private void bindHibernateEntityAnnotation(EntityBinding entityBinding) { AnnotationInstance hibernateEntityAnnotation = JandexHelper.getSingleAnnotation( configuredClass.getClassInfo(), HibernateDotNames.ENTITY diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/MappedAttribute.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/MappedAttribute.java index e678edbb44..44c09244d6 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/MappedAttribute.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/MappedAttribute.java @@ -42,18 +42,22 @@ public class MappedAttribute implements Comparable { private final Class type; private final Map> annotations; private final ColumnValues columnValues; + private final boolean isId; MappedAttribute(String name, Class type, Map> annotations) { this.name = name; this.type = type; this.annotations = annotations; + List idAnnotations = annotations.get( JPADotNames.ID ); + isId = idAnnotations != null && !idAnnotations.isEmpty(); + List columnAnnotations = annotations.get( JPADotNames.COLUMN ); if ( columnAnnotations != null && columnAnnotations.size() > 1 ) { throw new AssertionFailure( "There can only be one @Column annotation per mapped attribute" ); } AnnotationInstance columnAnnotation = columnAnnotations == null ? null : columnAnnotations.get( 0 ); - columnValues = new ColumnValues( columnAnnotation ); + columnValues = new ColumnValues( columnAnnotation, isId ); } public final String getName() { @@ -68,6 +72,10 @@ public class MappedAttribute implements Comparable { return columnValues; } + public boolean isId() { + return isId; + } + public final List annotations(DotName annotationDotName) { if ( annotations.containsKey( annotationDotName ) ) { return annotations.get( annotationDotName ); diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java index d43cd7bec3..3f4f912af8 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/binding/BasicAnnotationBindingTests.java @@ -38,7 +38,7 @@ import org.hibernate.testing.FailureExpected; */ public class BasicAnnotationBindingTests extends AbstractBasicBindingTests { - @FailureExpected(jiraKey = "HHH-5672", message = "Work in progress") + //@FailureExpected(jiraKey = "HHH-5672", message = "Work in progress") @Test public void testSimpleEntityMapping() { super.testSimpleEntityMapping();