diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java index dd26cf923865..0b0f9384c1c4 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EmbeddableBinder.java @@ -648,7 +648,7 @@ private static List collectClassElements( //embeddable elements can have type defs final PropertyContainer container = new PropertyContainer( returnedClassOrElement, annotatedClass, propertyAccessor ); - addElementsOfClass( classElements, container, context); + addElementsOfClass( classElements, container, context, 0 ); //add elements of the embeddable's mapped superclasses ClassDetails subclass = returnedClassOrElement; ClassDetails superClass; @@ -659,7 +659,7 @@ private static List collectClassElements( annotatedClass, propertyAccessor ); - addElementsOfClass( classElements, superContainer, context ); + addElementsOfClass( classElements, superContainer, context, 0 ); if ( subclassToSuperclass != null ) { subclassToSuperclass.put( subclass.getName(), superClass.getName() ); } @@ -690,7 +690,7 @@ private static void collectSubclassElements( assert put == null; // collect property of subclass final PropertyContainer superContainer = new PropertyContainer( subclass, superclass, propertyAccessor ); - addElementsOfClass( classElements, superContainer, context ); + addElementsOfClass( classElements, superContainer, context, 0 ); // recursively do that same for all subclasses collectSubclassElements( propertyAccessor, @@ -764,7 +764,7 @@ private static List collectBaseClassElements( entityAtStake, propertyAccessor ); - addElementsOfClass( baseClassElements, container, context ); + addElementsOfClass( baseClassElements, container, context, 0 ); baseReturnedClassOrElement = baseReturnedClassOrElement.determineRawClass().getGenericSuperType(); } return baseClassElements; diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java index afe23915b7df..fc6259bc7f8a 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java @@ -633,7 +633,8 @@ private static PropertyData getUniqueIdPropertyFromBaseClass( inferredData.getPropertyType(), propertyAccessor ); - addElementsOfClass( baseClassElements, propContainer, context ); + final int idPropertyCount = addElementsOfClass( baseClassElements, propContainer, context, 0 ); + assert idPropertyCount == 1; //Id properties are on top and there is only one return baseClassElements.get( 0 ); } diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/InheritanceState.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/InheritanceState.java index d9830b5a8652..c149b6806297 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/InheritanceState.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/InheritanceState.java @@ -235,12 +235,11 @@ private ElementsToProcess getElementsToProcess() { classDetails, accessType ); - int currentIdPropertyCount = addElementsOfClass( + idPropertyCount = addElementsOfClass( elements, propertyContainer, - buildingContext - ); - idPropertyCount += currentIdPropertyCount; + buildingContext, + idPropertyCount ); } if ( idPropertyCount == 0 && !inheritanceState.hasParents() ) { diff --git a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java index 694079b14c7e..076392967515 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/model/internal/PropertyBinder.java @@ -583,17 +583,17 @@ private void validateOptimisticLock(boolean excluded) { /** * @param elements List of {@link PropertyData} instances * @param propertyContainer Metadata about a class and its properties + * @param idPropertyCounter number of id properties already present in list of {@link PropertyData} instances * - * @return the number of id properties found while iterating the elements of - * {@code annotatedClass} using the determined access strategy + * @return total number of id properties found after iterating the elements of {@code annotatedClass} + * using the determined access strategy (starting from the provided {@code idPropertyCounter}) */ static int addElementsOfClass( List elements, PropertyContainer propertyContainer, - MetadataBuildingContext context) { - int idPropertyCounter = 0; + MetadataBuildingContext context, int idPropertyCounter) { for ( MemberDetails property : propertyContainer.propertyIterator() ) { - idPropertyCounter += addProperty( propertyContainer, property, elements, context ); + idPropertyCounter = addProperty( propertyContainer, property, elements, context, idPropertyCounter ); } return idPropertyCounter; } @@ -602,20 +602,20 @@ private static int addProperty( PropertyContainer propertyContainer, MemberDetails property, List inFlightPropertyDataList, - MetadataBuildingContext context) { + MetadataBuildingContext context, + int idPropertyCounter) { // see if inFlightPropertyDataList already contains a PropertyData for this name, // and if so, skip it... for ( PropertyData propertyData : inFlightPropertyDataList ) { if ( propertyData.getPropertyName().equals( property.resolveAttributeName() ) ) { checkIdProperty( property, propertyData ); // EARLY EXIT!!! - return 0; + return idPropertyCounter; } } final ClassDetails declaringClass = propertyContainer.getDeclaringClass(); final TypeVariableScope ownerType = propertyContainer.getTypeAtStake(); - int idPropertyCounter = 0; final PropertyData propertyAnnotatedElement = new PropertyInferredData( declaringClass, ownerType, @@ -628,7 +628,7 @@ private static int addProperty( // before any association by Hibernate final MemberDetails element = propertyAnnotatedElement.getAttributeMember(); if ( hasIdAnnotation( element ) ) { - inFlightPropertyDataList.add( 0, propertyAnnotatedElement ); + inFlightPropertyDataList.add( idPropertyCounter, propertyAnnotatedElement ); handleIdProperty( propertyContainer, context, declaringClass, ownerType, element ); if ( hasToOneAnnotation( element ) ) { context.getMetadataCollector() diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/hbm/joinformula/JoinColumnAndFormulaTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/hbm/joinformula/JoinColumnAndFormulaTests.java index 958e5bf27dda..031ff36ba209 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/hbm/joinformula/JoinColumnAndFormulaTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/boot/models/hbm/joinformula/JoinColumnAndFormulaTests.java @@ -13,7 +13,6 @@ import org.hibernate.testing.orm.junit.DomainModel; import org.hibernate.testing.orm.junit.DomainModelScope; -import org.hibernate.testing.orm.junit.FailureExpected; import org.hibernate.testing.orm.junit.ServiceRegistry; import org.hibernate.testing.orm.junit.Setting; import org.junit.jupiter.api.Test; @@ -40,7 +39,6 @@ void testAnnotations(DomainModelScope domainModelScope) { @Test @ServiceRegistry( settings = @Setting( name= MappingSettings.TRANSFORM_HBM_XML, value = "true" ) ) @DomainModel( xmlMappings = "mappings/models/hbm/joinformula/many-to-one-join-column-and-formula.xml" ) - @FailureExpected( reason = "@JoinColumnsOrFormulas broken", jiraKey = "https://hibernate.atlassian.net/browse/HHH-18384" ) void testHbmXmlTransformed(DomainModelScope domainModelScope) { verifyMapping( domainModelScope ); }