From 33faa5b0603ec292851ba099e4403e6ea883e26e Mon Sep 17 00:00:00 2001 From: Gavin Date: Sun, 11 Dec 2022 14:15:45 +0100 Subject: [PATCH] HHH-15847 run AttributeBinders in a SecondPass so that they can do stuff like register converters and not have the results hammered by the SecondPass registered by BasicValueBinder. --- .../InFlightMetadataCollectorImpl.java | 1 + .../cfg/annotations/PropertyBinder.java | 29 ++++++++++-------- .../mapping/attributebinder/YesNoBinder.java | 30 ++++--------------- 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java index 58554995b1..09f5fa728c 100644 --- a/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java +++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/InFlightMetadataCollectorImpl.java @@ -1766,6 +1766,7 @@ public class InFlightMetadataCollectorImpl implements InFlightMetadataCollector, * Ugh! But we need this done before we ask Envers to produce its entities. */ public void processSecondPasses(MetadataBuildingContext buildingContext) { + assert !inSecondPass; inSecondPass = true; try { diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java index 9c4eb954d6..99e5a0134f 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/PropertyBinder.java @@ -41,7 +41,6 @@ import org.hibernate.mapping.KeyValue; import org.hibernate.mapping.MappedSuperclass; import org.hibernate.mapping.Property; import org.hibernate.mapping.RootClass; -import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.ToOne; import org.hibernate.mapping.Value; import org.hibernate.metamodel.spi.EmbeddableInstantiator; @@ -232,8 +231,8 @@ public class PropertyBinder { basicValueBinder.setAccessType( accessType ); - final SimpleValue propertyValue = basicValueBinder.make(); - setValue( propertyValue ); + value = basicValueBinder.make(); + return makeProperty(); } @@ -266,7 +265,7 @@ public class PropertyBinder { this.isXToMany = xToMany; } - private Property bind(Property prop) { + private Property bind(Property property) { if ( isId ) { final RootClass rootClass = (RootClass) holder.getPersistentClass(); //if an xToMany, it has to be wrapped today. @@ -280,7 +279,7 @@ public class PropertyBinder { new PropertyPreloadedData(null, null, null), true, false, - resolveCustomInstantiator( property, returnedClass ), + resolveCustomInstantiator(this.property, returnedClass ), buildingContext ); rootClass.setIdentifier( identifier ); @@ -289,7 +288,7 @@ public class PropertyBinder { rootClass.setIdentifierMapper( identifier ); } //FIXME is it good enough? - identifier.addProperty( prop ); + identifier.addProperty( property ); } else { rootClass.setIdentifier( (KeyValue) getValue() ); @@ -297,29 +296,34 @@ public class PropertyBinder { rootClass.setEmbeddedIdentifier( true ); } else { - rootClass.setIdentifierProperty( prop ); + rootClass.setIdentifierProperty( property ); final MappedSuperclass superclass = getMappedSuperclassOrNull( declaringClass, inheritanceStatePerClass, buildingContext ); if ( superclass != null ) { - superclass.setDeclaredIdentifierProperty(prop); + superclass.setDeclaredIdentifierProperty(property); } else { //we know the property is on the actual entity - rootClass.setDeclaredIdentifierProperty( prop ); + rootClass.setDeclaredIdentifierProperty( property ); } } } } else { - holder.addProperty( prop, columns, declaringClass ); + holder.addProperty( property, columns, declaringClass ); } - callAttributeBinders( prop ); + if ( buildingContext.getMetadataCollector().isInSecondPass() ) { + callAttributeBinders( property ); + } + else { + buildingContext.getMetadataCollector().addSecondPass( persistentClasses -> callAttributeBinders( property ) ); + } - return prop; + return property; } private Class resolveCustomInstantiator(XProperty property, XClass embeddableClass) { @@ -370,6 +374,7 @@ public class PropertyBinder { property.setUpdateable( updatable ); LOG.tracev( "Cascading {0} with {1}", name, cascade ); + return property; } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/attributebinder/YesNoBinder.java b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/attributebinder/YesNoBinder.java index c8f69bcc2a..9be4039c7c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/attributebinder/YesNoBinder.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/mapping/attributebinder/YesNoBinder.java @@ -6,17 +6,13 @@ */ package org.hibernate.orm.test.mapping.attributebinder; -import java.sql.Types; - import org.hibernate.boot.model.convert.internal.InstanceBasedConverterDescriptor; import org.hibernate.boot.spi.MetadataBuildingContext; -import org.hibernate.mapping.BasicValue; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.binder.AttributeBinder; +import org.hibernate.mapping.SimpleValue; import org.hibernate.type.YesNoConverter; -import org.hibernate.type.descriptor.java.BasicJavaType; -import org.hibernate.type.descriptor.jdbc.JdbcType; //tag::attribute-binder-example[] /** @@ -29,26 +25,12 @@ public class YesNoBinder implements AttributeBinder { MetadataBuildingContext buildingContext, PersistentClass persistentClass, Property property) { - final BasicValue booleanValueMapping = (BasicValue) property.getValue(); - - final BasicJavaType javaType = (BasicJavaType) buildingContext.getBootstrapContext() - .getTypeConfiguration() - .getJavaTypeRegistry() - .getDescriptor( Boolean.class ); - - final JdbcType jdbcType = buildingContext.getBootstrapContext() - .getTypeConfiguration() - .getJdbcTypeRegistry() - .getDescriptor( Types.CHAR ); - - final InstanceBasedConverterDescriptor converter = new InstanceBasedConverterDescriptor( - YesNoConverter.INSTANCE, - buildingContext.getBootstrapContext().getClassmateContext() + ( (SimpleValue) property.getValue() ).setJpaAttributeConverterDescriptor( + new InstanceBasedConverterDescriptor( + YesNoConverter.INSTANCE, + buildingContext.getBootstrapContext().getClassmateContext() + ) ); - - booleanValueMapping.setExplicitJavaTypeAccess( (typeConfiguration) -> javaType ); - booleanValueMapping.setExplicitJdbcTypeAccess( (typeConfiguration) -> jdbcType ); - booleanValueMapping.setJpaAttributeConverterDescriptor( converter ); } } //end::attribute-binder-example[]