code cleanups to Binders

This commit is contained in:
Gavin King 2024-11-11 16:54:04 +01:00
parent f1760ce6a2
commit f7a8144e3c
8 changed files with 210 additions and 185 deletions

View File

@ -254,6 +254,14 @@ public abstract class CollectionBinder {
this.buildingContext = buildingContext; this.buildingContext = buildingContext;
} }
private String getRole() {
return collection.getRole();
}
private InFlightMetadataCollector getMetadataCollector() {
return buildingContext.getMetadataCollector();
}
/** /**
* The first pass at binding a collection. * The first pass at binding a collection.
*/ */
@ -859,7 +867,9 @@ public abstract class CollectionBinder {
MetadataBuildingContext buildingContext) { MetadataBuildingContext buildingContext) {
final CollectionBinder binder; final CollectionBinder binder;
final CollectionType typeAnnotation = property.getAnnotationUsage( CollectionType.class, buildingContext.getMetadataCollector().getSourceModelBuildingContext() ); final CollectionType typeAnnotation =
property.getAnnotationUsage( CollectionType.class,
buildingContext.getMetadataCollector().getSourceModelBuildingContext() );
if ( typeAnnotation != null ) { if ( typeAnnotation != null ) {
binder = createBinderFromCustomTypeAnnotation( property, typeAnnotation, buildingContext ); binder = createBinderFromCustomTypeAnnotation( property, typeAnnotation, buildingContext );
// todo (6.0) - technically, these should no longer be needed // todo (6.0) - technically, these should no longer be needed
@ -1174,8 +1184,8 @@ public abstract class CollectionBinder {
} }
public void setTargetEntity(Class<?> targetEntity) { public void setTargetEntity(Class<?> targetEntity) {
final SourceModelBuildingContext sourceModelContext = buildingContext.getMetadataCollector().getSourceModelBuildingContext(); final ClassDetailsRegistry classDetailsRegistry =
final ClassDetailsRegistry classDetailsRegistry = sourceModelContext.getClassDetailsRegistry(); getMetadataCollector().getSourceModelBuildingContext().getClassDetailsRegistry();
setTargetEntity( classDetailsRegistry.resolveClassDetails( targetEntity.getName() ) ); setTargetEntity( classDetailsRegistry.resolveClassDetails( targetEntity.getName() ) );
} }
@ -1225,7 +1235,7 @@ public abstract class CollectionBinder {
//TODO reduce tableBinder != null and oneToMany //TODO reduce tableBinder != null and oneToMany
scheduleSecondPass( isUnowned ); scheduleSecondPass( isUnowned );
buildingContext.getMetadataCollector().addCollectionBinding( collection ); getMetadataCollector().addCollectionBinding( collection );
bindProperty(); bindProperty();
} }
@ -1245,7 +1255,7 @@ public abstract class CollectionBinder {
} }
private void scheduleSecondPass(boolean isMappedBy) { private void scheduleSecondPass(boolean isMappedBy) {
final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); final InFlightMetadataCollector metadataCollector = getMetadataCollector();
//many to many may need some second pass information //many to many may need some second pass information
if ( !oneToMany && isMappedBy ) { if ( !oneToMany && isMappedBy ) {
metadataCollector.addMappedBy( getElementType().getName(), mappedBy, propertyName ); metadataCollector.addMappedBy( getElementType().getName(), mappedBy, propertyName );
@ -1274,7 +1284,7 @@ public abstract class CollectionBinder {
private void bindExplicitTypes() { private void bindExplicitTypes() {
// set explicit type information // set explicit type information
final InFlightMetadataCollector metadataCollector = buildingContext.getMetadataCollector(); final InFlightMetadataCollector metadataCollector = getMetadataCollector();
if ( explicitType != null ) { if ( explicitType != null ) {
final TypeDefinition typeDef = metadataCollector.getTypeDefinition( explicitType ); final TypeDefinition typeDef = metadataCollector.getTypeDefinition( explicitType );
if ( typeDef == null ) { if ( typeDef == null ) {
@ -1402,7 +1412,7 @@ public abstract class CollectionBinder {
final SQLSelect sqlSelect = property.getDirectAnnotationUsage( SQLSelect.class ); final SQLSelect sqlSelect = property.getDirectAnnotationUsage( SQLSelect.class );
if ( sqlSelect != null ) { if ( sqlSelect != null ) {
final String loaderName = collection.getRole() + "$SQLSelect"; final String loaderName = getRole() + "$SQLSelect";
collection.setLoaderName( loaderName ); collection.setLoaderName( loaderName );
// TODO: pass in the collection element type here // TODO: pass in the collection element type here
QueryBinder.bindNativeQuery( loaderName, sqlSelect, null, buildingContext ); QueryBinder.bindNativeQuery( loaderName, sqlSelect, null, buildingContext );
@ -1410,7 +1420,7 @@ public abstract class CollectionBinder {
final HQLSelect hqlSelect = property.getDirectAnnotationUsage( HQLSelect.class ); final HQLSelect hqlSelect = property.getDirectAnnotationUsage( HQLSelect.class );
if ( hqlSelect != null ) { if ( hqlSelect != null ) {
final String loaderName = collection.getRole() + "$HQLSelect"; final String loaderName = getRole() + "$HQLSelect";
collection.setLoaderName( loaderName ); collection.setLoaderName( loaderName );
QueryBinder.bindQuery( loaderName, hqlSelect, buildingContext ); QueryBinder.bindQuery( loaderName, hqlSelect, buildingContext );
} }
@ -1517,12 +1527,12 @@ public abstract class CollectionBinder {
} }
private SourceModelBuildingContext sourceModelContext() { private SourceModelBuildingContext sourceModelContext() {
return buildingContext.getMetadataCollector().getSourceModelBuildingContext(); return getMetadataCollector().getSourceModelBuildingContext();
} }
private void handleFetchProfileOverrides() { private void handleFetchProfileOverrides() {
property.forEachAnnotationUsage( FetchProfileOverride.class, sourceModelContext(), (usage) -> { property.forEachAnnotationUsage( FetchProfileOverride.class, sourceModelContext(), (usage) -> {
buildingContext.getMetadataCollector().addSecondPass( new FetchSecondPass( getMetadataCollector().addSecondPass( new FetchSecondPass(
usage, usage,
propertyHolder, propertyHolder,
propertyName, propertyName,
@ -1702,7 +1712,7 @@ public abstract class CollectionBinder {
} }
oneToMany.setAssociatedClass( associatedClass ); oneToMany.setAssociatedClass( associatedClass );
final Map<String, Join> joins = buildingContext.getMetadataCollector().getJoins( referencedEntityName ); final Map<String, Join> joins = getMetadataCollector().getJoins( referencedEntityName );
foreignJoinColumns.setPropertyHolder( buildPropertyHolder( foreignJoinColumns.setPropertyHolder( buildPropertyHolder(
associatedClass, associatedClass,
joins, joins,
@ -1717,7 +1727,7 @@ public abstract class CollectionBinder {
collection.setCollectionTable( foreignJoinColumns.getTable() ); collection.setCollectionTable( foreignJoinColumns.getTable() );
} }
if ( LOG.isDebugEnabled() ) { if ( LOG.isDebugEnabled() ) {
LOG.debugf( "Mapping collection: %s -> %s", collection.getRole(), collection.getCollectionTable().getName() ); LOG.debugf( "Mapping collection: %s -> %s", getRole(), collection.getCollectionTable().getName() );
} }
bindSynchronize(); bindSynchronize();
@ -1733,7 +1743,7 @@ public abstract class CollectionBinder {
} }
private void createOneToManyBackref(org.hibernate.mapping.OneToMany oneToMany) { private void createOneToManyBackref(org.hibernate.mapping.OneToMany oneToMany) {
final InFlightMetadataCollector collector = buildingContext.getMetadataCollector(); final InFlightMetadataCollector collector = getMetadataCollector();
// for non-inverse one-to-many, with a not-null fk, add a backref! // for non-inverse one-to-many, with a not-null fk, add a backref!
final String entityName = oneToMany.getReferencedEntityName(); final String entityName = oneToMany.getReferencedEntityName();
final PersistentClass referenced = collector.getEntityBinding( entityName ); final PersistentClass referenced = collector.getEntityBinding( entityName );
@ -1745,15 +1755,16 @@ public abstract class CollectionBinder {
backref.setOptional( true ); backref.setOptional( true );
backref.setUpdateable( false); backref.setUpdateable( false);
backref.setSelectable( false ); backref.setSelectable( false );
backref.setCollectionRole( collection.getRole() ); backref.setCollectionRole( getRole() );
backref.setEntityName( collection.getOwner().getEntityName() ); backref.setEntityName( collection.getOwner().getEntityName() );
backref.setValue( collection.getKey() ); backref.setValue( collection.getKey() );
referenced.addProperty( backref ); referenced.addProperty( backref );
} }
private void handleJpaOrderBy(Collection collection, PersistentClass associatedClass) { private void handleJpaOrderBy(Collection collection, PersistentClass associatedClass) {
if ( jpaOrderBy != null ) { final String hqlOrderBy = extractHqlOrderBy( jpaOrderBy );
final String orderByFragment = buildOrderByClauseFromHql( jpaOrderBy.value(), associatedClass ); if ( hqlOrderBy != null ) {
final String orderByFragment = buildOrderByClauseFromHql( hqlOrderBy, associatedClass );
if ( isNotEmpty( orderByFragment ) ) { if ( isNotEmpty( orderByFragment ) ) {
collection.setOrderBy( orderByFragment ); collection.setOrderBy( orderByFragment );
} }
@ -1763,22 +1774,20 @@ public abstract class CollectionBinder {
private void bindSynchronize() { private void bindSynchronize() {
final Synchronize synchronizeAnnotation = property.getDirectAnnotationUsage( Synchronize.class ); final Synchronize synchronizeAnnotation = property.getDirectAnnotationUsage( Synchronize.class );
if ( synchronizeAnnotation != null ) { if ( synchronizeAnnotation != null ) {
final JdbcEnvironment jdbcEnvironment = buildingContext.getMetadataCollector().getDatabase().getJdbcEnvironment();
for ( String table : synchronizeAnnotation.value() ) { for ( String table : synchronizeAnnotation.value() ) {
String physicalName = synchronizeAnnotation.logical() final String physicalName =
? toPhysicalName( jdbcEnvironment, table ) synchronizeAnnotation.logical()
: table; ? toPhysicalName( table )
: table;
collection.addSynchronizedTable( physicalName ); collection.addSynchronizedTable( physicalName );
} }
} }
} }
private String toPhysicalName(JdbcEnvironment jdbcEnvironment, String logicalName) { private String toPhysicalName(String logicalName) {
final JdbcEnvironment jdbcEnvironment = getMetadataCollector().getDatabase().getJdbcEnvironment();
return buildingContext.getBuildingOptions().getPhysicalNamingStrategy() return buildingContext.getBuildingOptions().getPhysicalNamingStrategy()
.toPhysicalTableName( .toPhysicalTableName( jdbcEnvironment.getIdentifierHelper().toIdentifier( logicalName ), jdbcEnvironment )
jdbcEnvironment.getIdentifierHelper().toIdentifier( logicalName ),
jdbcEnvironment
)
.render( jdbcEnvironment.getDialect() ); .render( jdbcEnvironment.getDialect() );
} }
@ -1863,7 +1872,8 @@ public abstract class CollectionBinder {
} }
private String getWhereJoinTableClause() { private String getWhereJoinTableClause() {
final SQLJoinTableRestriction joinTableRestriction = property.getDirectAnnotationUsage( SQLJoinTableRestriction.class ); final SQLJoinTableRestriction joinTableRestriction =
property.getDirectAnnotationUsage( SQLJoinTableRestriction.class );
return joinTableRestriction != null ? joinTableRestriction.value() : null; return joinTableRestriction != null ? joinTableRestriction.value() : null;
} }
@ -1878,7 +1888,8 @@ public abstract class CollectionBinder {
} }
private String getWhereOnCollectionClause() { private String getWhereOnCollectionClause() {
final SQLRestriction restrictionOnCollection = getOverridableAnnotation( property, SQLRestriction.class, getBuildingContext() ); final SQLRestriction restrictionOnCollection =
getOverridableAnnotation( property, SQLRestriction.class, getBuildingContext() );
return restrictionOnCollection != null ? restrictionOnCollection.value() : null; return restrictionOnCollection != null ? restrictionOnCollection.value() : null;
} }
@ -1939,7 +1950,7 @@ public abstract class CollectionBinder {
} }
private String getDefaultFilterCondition(String name, Annotation annotation) { private String getDefaultFilterCondition(String name, Annotation annotation) {
final FilterDefinition definition = buildingContext.getMetadataCollector().getFilterDefinition( name ); final FilterDefinition definition = getMetadataCollector().getFilterDefinition( name );
if ( definition == null ) { if ( definition == null ) {
throw new AnnotationException( "Collection '" + qualify( propertyHolder.getPath(), propertyName ) throw new AnnotationException( "Collection '" + qualify( propertyHolder.getPath(), propertyName )
+ "' has a '@" + annotation.annotationType().getSimpleName() + "' has a '@" + annotation.annotationType().getSimpleName()
@ -1981,6 +1992,7 @@ public abstract class CollectionBinder {
public void setMapKey(MapKey key) { public void setMapKey(MapKey key) {
hasMapKeyProperty = key != null; hasMapKeyProperty = key != null;
if ( hasMapKeyProperty ) { if ( hasMapKeyProperty ) {
// JPA says: if missing, use primary key of associated entity
mapKeyPropertyName = nullIfEmpty( key.name() ); mapKeyPropertyName = nullIfEmpty( key.name() );
} }
} }
@ -2167,7 +2179,7 @@ public abstract class CollectionBinder {
final String entityName = joinColumns.getManyToManyOwnerSideEntityName() != null final String entityName = joinColumns.getManyToManyOwnerSideEntityName() != null
? "inverse__" + joinColumns.getManyToManyOwnerSideEntityName() ? "inverse__" + joinColumns.getManyToManyOwnerSideEntityName()
: joinColumns.getPropertyHolder().getEntityName(); : joinColumns.getPropertyHolder().getEntityName();
final InFlightMetadataCollector collector = buildingContext.getMetadataCollector(); final InFlightMetadataCollector collector = getMetadataCollector();
final String referencedProperty = collector.getPropertyReferencedAssociation( entityName, mappedBy ); final String referencedProperty = collector.getPropertyReferencedAssociation( entityName, mappedBy );
if ( referencedProperty != null ) { if ( referencedProperty != null ) {
collection.setReferencedPropertyName( referencedProperty ); collection.setReferencedPropertyName( referencedProperty );
@ -2238,14 +2250,8 @@ public abstract class CollectionBinder {
propertyHolder.startingProperty( property ); propertyHolder.startingProperty( property );
} }
final CollectionPropertyHolder holder = buildPropertyHolder( final CollectionPropertyHolder holder =
collection, buildPropertyHolder( collection, getRole(), elementClass, property, propertyHolder, buildingContext );
collection.getRole(),
elementClass,
property,
propertyHolder,
buildingContext
);
final Class<? extends CompositeUserType<?>> compositeUserType = final Class<? extends CompositeUserType<?>> compositeUserType =
resolveCompositeUserType( property, elementClass, buildingContext ); resolveCompositeUserType( property, elementClass, buildingContext );
@ -2370,13 +2376,13 @@ public abstract class CollectionBinder {
// todo : force in the case of Convert annotation(s) with embedded paths (beyond key/value prefixes)? // todo : force in the case of Convert annotation(s) with embedded paths (beyond key/value prefixes)?
return isEmbedded || attributeOverride return isEmbedded || attributeOverride
? EMBEDDABLE ? EMBEDDABLE
: buildingContext.getMetadataCollector().getClassType( elementClass ); : getMetadataCollector().getClassType( elementClass );
} }
} }
protected boolean mappingDefinedAttributeOverrideOnElement(MemberDetails property) { protected boolean mappingDefinedAttributeOverrideOnElement(MemberDetails property) {
return property.hasDirectAnnotationUsage( AttributeOverride.class ) return property.hasDirectAnnotationUsage( AttributeOverride.class )
|| property.hasDirectAnnotationUsage( AttributeOverrides.class ); || property.hasDirectAnnotationUsage( AttributeOverrides.class );
} }
static AnnotatedColumns createElementColumnsIfNecessary( static AnnotatedColumns createElementColumnsIfNecessary(
@ -2516,7 +2522,7 @@ public abstract class CollectionBinder {
private void handleOwnedManyToMany(PersistentClass collectionEntity, boolean isCollectionOfEntities) { private void handleOwnedManyToMany(PersistentClass collectionEntity, boolean isCollectionOfEntities) {
//TODO: only for implicit columns? //TODO: only for implicit columns?
//FIXME NamingStrategy //FIXME NamingStrategy
final InFlightMetadataCollector collector = buildingContext.getMetadataCollector(); final InFlightMetadataCollector collector = getMetadataCollector();
final PersistentClass owner = collection.getOwner(); final PersistentClass owner = collection.getOwner();
joinColumns.setMappedBy( joinColumns.setMappedBy(
owner.getEntityName(), owner.getEntityName(),
@ -2616,11 +2622,12 @@ public abstract class CollectionBinder {
+ "' which does not exist in the target entity '" + elementType.getName() + "'" ); + "' which does not exist in the target entity '" + elementType.getName() + "'" );
} }
final Value otherSidePropertyValue = otherSideProperty.getValue(); final Value otherSidePropertyValue = otherSideProperty.getValue();
final Table table = otherSidePropertyValue instanceof Collection final Table table =
// this is a collection on the other side otherSidePropertyValue instanceof Collection collectionProperty
? ( (Collection) otherSidePropertyValue ).getCollectionTable() // this is a collection on the other side
// this is a ToOne with a @JoinTable or a regular property ? collectionProperty.getCollectionTable()
: otherSidePropertyValue.getTable(); // this is a ToOne with a @JoinTable or a regular property
: otherSidePropertyValue.getTable();
collection.setCollectionTable( table ); collection.setCollectionTable( table );
processSoftDeletes(); processSoftDeletes();
@ -2666,7 +2673,7 @@ public abstract class CollectionBinder {
return " targets the type '" + elementType.getName() + "'" + problem; return " targets the type '" + elementType.getName() + "'" + problem;
} }
private Class<? extends EmbeddableInstantiator> resolveCustomInstantiator( private static Class<? extends EmbeddableInstantiator> resolveCustomInstantiator(
MemberDetails property, MemberDetails property,
TypeDetails propertyClass, TypeDetails propertyClass,
MetadataBuildingContext context) { MetadataBuildingContext context) {
@ -2710,15 +2717,12 @@ public abstract class CollectionBinder {
return null; return null;
} }
private String extractHqlOrderBy(OrderBy jpaOrderBy) { private static String extractHqlOrderBy(OrderBy jpaOrderBy) {
if ( jpaOrderBy != null ) { return jpaOrderBy != null
// Null not possible. In case of empty expression, apply default ordering. // Null not possible. In case of empty expression, apply default ordering.
return jpaOrderBy.value(); ? jpaOrderBy.value()
} // @OrderBy not found.
else { : null;
// @OrderBy not found.
return null;
}
} }
private static void checkFilterConditions(Collection collection) { private static void checkFilterConditions(Collection collection) {
@ -2859,21 +2863,22 @@ public abstract class CollectionBinder {
for ( Selectable selectable: mappedByColumns ) { for ( Selectable selectable: mappedByColumns ) {
firstColumn.linkValueUsingAColumnCopy( (Column) selectable, value); firstColumn.linkValueUsingAColumnCopy( (Column) selectable, value);
} }
final String referencedPropertyName = buildingContext.getMetadataCollector() final InFlightMetadataCollector metadataCollector = getMetadataCollector();
.getPropertyReferencedAssociation( targetEntity.getEntityName(), mappedBy ); final String referencedPropertyName =
metadataCollector.getPropertyReferencedAssociation( targetEntity.getEntityName(), mappedBy );
final ManyToOne manyToOne = (ManyToOne) value;
if ( referencedPropertyName != null ) { if ( referencedPropertyName != null ) {
//TODO always a many to one? //TODO always a many to one?
( (ManyToOne) value).setReferencedPropertyName( referencedPropertyName ); manyToOne.setReferencedPropertyName( referencedPropertyName );
buildingContext.getMetadataCollector() metadataCollector.addUniquePropertyReference( targetEntity.getEntityName(), referencedPropertyName );
.addUniquePropertyReference( targetEntity.getEntityName(), referencedPropertyName );
} }
( (ManyToOne) value).setReferenceToPrimaryKey( referencedPropertyName == null ); manyToOne.setReferenceToPrimaryKey( referencedPropertyName == null );
value.createForeignKey(); value.createForeignKey();
} }
private static List<Selectable> mappedByColumns(PersistentClass referencedEntity, Property property) { private static List<Selectable> mappedByColumns(PersistentClass referencedEntity, Property property) {
if ( property.getValue() instanceof Collection ) { if ( property.getValue() instanceof Collection collection ) {
return ( (Collection) property.getValue() ).getKey().getSelectables(); return collection.getKey().getSelectables();
} }
else { else {
//find the appropriate reference key, can be in a join //find the appropriate reference key, can be in a join

View File

@ -201,7 +201,11 @@ public class EntityBinder {
private CacheLayout queryCacheLayout; private CacheLayout queryCacheLayout;
private SourceModelBuildingContext getSourceModelContext() { private SourceModelBuildingContext getSourceModelContext() {
return context.getMetadataCollector().getSourceModelBuildingContext(); return getMetadataCollector().getSourceModelBuildingContext();
}
private InFlightMetadataCollector getMetadataCollector() {
return context.getMetadataCollector();
} }
/** /**
@ -215,12 +219,14 @@ public class EntityBinder {
LOG.debugf( "Binding entity from annotated class: %s", clazzToProcess.getName() ); LOG.debugf( "Binding entity from annotated class: %s", clazzToProcess.getName() );
} }
final InFlightMetadataCollector collector = context.getMetadataCollector();
//TODO: be more strict with secondary table allowance (not for ids, not for secondary table join columns etc) //TODO: be more strict with secondary table allowance (not for ids, not for secondary table join columns etc)
final InheritanceState inheritanceState = inheritanceStates.get( clazzToProcess ); final InheritanceState inheritanceState = inheritanceStates.get( clazzToProcess );
final PersistentClass superEntity = getSuperEntity( clazzToProcess, inheritanceStates, context, inheritanceState ); final PersistentClass superEntity = getSuperEntity( clazzToProcess, inheritanceStates, context, inheritanceState );
final PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity, context ); final PersistentClass persistentClass = makePersistentClass( inheritanceState, superEntity, context );
checkOverrides( clazzToProcess, superEntity, context.getMetadataCollector().getSourceModelBuildingContext() ); checkOverrides( clazzToProcess, superEntity, collector.getSourceModelBuildingContext() );
final EntityBinder entityBinder = new EntityBinder( clazzToProcess, persistentClass, context ); final EntityBinder entityBinder = new EntityBinder( clazzToProcess, persistentClass, context );
entityBinder.bindEntity(); entityBinder.bindEntity();
@ -240,7 +246,6 @@ public class EntityBinder {
entityBinder.handleInheritance( inheritanceState, superEntity, holder ); entityBinder.handleInheritance( inheritanceState, superEntity, holder );
entityBinder.handleIdentifier( holder, inheritanceStates, inheritanceState ); entityBinder.handleIdentifier( holder, inheritanceStates, inheritanceState );
final InFlightMetadataCollector collector = context.getMetadataCollector();
if ( persistentClass instanceof RootClass rootClass ) { if ( persistentClass instanceof RootClass rootClass ) {
collector.addSecondPass( new CreateKeySecondPass( rootClass ) ); collector.addSecondPass( new CreateKeySecondPass( rootClass ) );
bindSoftDelete( clazzToProcess, rootClass, context ); bindSoftDelete( clazzToProcess, rootClass, context );
@ -327,7 +332,8 @@ public class EntityBinder {
ClassDetails classToCheck = classDetails.getSuperClass(); ClassDetails classToCheck = classDetails.getSuperClass();
while ( classToCheck != null ) { while ( classToCheck != null ) {
final SoftDelete fromSuper = classToCheck.getAnnotationUsage( SoftDelete.class, sourceModelContext ); final SoftDelete fromSuper = classToCheck.getAnnotationUsage( SoftDelete.class, sourceModelContext );
if ( fromSuper != null && classToCheck.hasAnnotationUsage( jakarta.persistence.MappedSuperclass.class, sourceModelContext ) ) { if ( fromSuper != null
&& classToCheck.hasAnnotationUsage( jakarta.persistence.MappedSuperclass.class, sourceModelContext ) ) {
return fromSuper; return fromSuper;
} }
@ -366,7 +372,8 @@ public class EntityBinder {
} }
private void callTypeBinders(PersistentClass persistentClass) { private void callTypeBinders(PersistentClass persistentClass) {
final List<? extends Annotation> metaAnnotatedList = annotatedClass.getMetaAnnotated( TypeBinderType.class, getSourceModelContext() ); final List<? extends Annotation> metaAnnotatedList =
annotatedClass.getMetaAnnotated( TypeBinderType.class, getSourceModelContext() );
for ( Annotation metaAnnotated : metaAnnotatedList ) { for ( Annotation metaAnnotated : metaAnnotatedList ) {
applyTypeBinder( metaAnnotated, persistentClass ); applyTypeBinder( metaAnnotated, persistentClass );
} }
@ -424,9 +431,8 @@ public class EntityBinder {
TableBinder.addTableOptions( table, jpaTableUsage.options() ); TableBinder.addTableOptions( table, jpaTableUsage.options() );
} }
final InFlightMetadataCollector.EntityTableXref entityTableXref = context final InFlightMetadataCollector.EntityTableXref entityTableXref =
.getMetadataCollector() getMetadataCollector().getEntityTableXref( persistentClass.getEntityName() );
.getEntityTableXref( persistentClass.getEntityName() );
annotatedClass.forEachAnnotationUsage( jakarta.persistence.SecondaryTable.class, getSourceModelContext(), (usage) -> { annotatedClass.forEachAnnotationUsage( jakarta.persistence.SecondaryTable.class, getSourceModelContext(), (usage) -> {
final Identifier secondaryTableLogicalName = toIdentifier( usage.name() ); final Identifier secondaryTableLogicalName = toIdentifier( usage.name() );
@ -476,7 +482,9 @@ public class EntityBinder {
if ( classWithIdClass != null ) { if ( classWithIdClass != null ) {
final IdClass idClassAnn = classWithIdClass.getDirectAnnotationUsage( IdClass.class ); final IdClass idClassAnn = classWithIdClass.getDirectAnnotationUsage( IdClass.class );
final Class<?> idClassValue = idClassAnn.value(); final Class<?> idClassValue = idClassAnn.value();
final ClassDetails compositeClass = context.getMetadataCollector().getSourceModelBuildingContext().getClassDetailsRegistry().resolveClassDetails( idClassValue.getName() ); final ClassDetails compositeClass =
getMetadataCollector().getSourceModelBuildingContext().getClassDetailsRegistry()
.resolveClassDetails( idClassValue.getName() );
final TypeDetails compositeType = new ClassTypeDetailsImpl( compositeClass, TypeDetails.Kind.CLASS ); final TypeDetails compositeType = new ClassTypeDetailsImpl( compositeClass, TypeDetails.Kind.CLASS );
final TypeDetails classWithIdType = new ClassTypeDetailsImpl( classWithIdClass, TypeDetails.Kind.CLASS ); final TypeDetails classWithIdType = new ClassTypeDetailsImpl( classWithIdClass, TypeDetails.Kind.CLASS );
@ -657,7 +665,8 @@ public class EntityBinder {
} }
else { else {
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext(); final SourceModelBuildingContext sourceModelContext =
context.getMetadataCollector().getSourceModelBuildingContext();
final IdClass idClass = associatedClassWithIdClass.getAnnotationUsage( IdClass.class, sourceModelContext ); final IdClass idClass = associatedClassWithIdClass.getAnnotationUsage( IdClass.class, sourceModelContext );
return compositeClass.getName().equals( idClass.value().getName() ); return compositeClass.getName().equals( idClass.value().getName() );
} }
@ -731,7 +740,8 @@ public class EntityBinder {
final String table; final String table;
final String catalog; final String catalog;
final UniqueConstraint[] uniqueConstraints; final UniqueConstraint[] uniqueConstraints;
final jakarta.persistence.Table tableAnnotation = annotatedClass.getAnnotationUsage( jakarta.persistence.Table.class, getSourceModelContext() ); final jakarta.persistence.Table tableAnnotation =
annotatedClass.getAnnotationUsage( jakarta.persistence.Table.class, getSourceModelContext() );
if ( tableAnnotation != null ) { if ( tableAnnotation != null ) {
table = tableAnnotation.name(); table = tableAnnotation.name();
schema = tableAnnotation.schema(); schema = tableAnnotation.schema();
@ -778,7 +788,7 @@ public class EntityBinder {
rowId == null ? null : rowId.value(), rowId == null ? null : rowId.value(),
view == null ? null : view.query(), view == null ? null : view.query(),
inheritanceState.hasDenormalizedTable() inheritanceState.hasDenormalizedTable()
? context.getMetadataCollector().getEntityTableXref( superEntity.getEntityName() ) ? getMetadataCollector().getEntityTableXref( superEntity.getEntityName() )
: null : null
); );
} }
@ -838,10 +848,9 @@ public class EntityBinder {
final OnDelete onDelete = annotatedClass.getAnnotationUsage( OnDelete.class, getSourceModelContext() ); final OnDelete onDelete = annotatedClass.getAnnotationUsage( OnDelete.class, getSourceModelContext() );
key.setOnDeleteAction( onDelete == null ? null : onDelete.action() ); key.setOnDeleteAction( onDelete == null ? null : onDelete.action() );
//we are never in a second pass at that stage, so queue it //we are never in a second pass at that stage, so queue it
context.getMetadataCollector() final InFlightMetadataCollector metadataCollector = getMetadataCollector();
.addSecondPass( new JoinedSubclassFkSecondPass( jsc, joinColumns, key, context) ); metadataCollector.addSecondPass( new JoinedSubclassFkSecondPass( jsc, joinColumns, key, context) );
context.getMetadataCollector() metadataCollector.addSecondPass( new CreateKeySecondPass( jsc ) );
.addSecondPass( new CreateKeySecondPass( jsc ) );
} }
final AnnotatedDiscriminatorColumn discriminatorColumn = processJoinedDiscriminatorProperties( state ); final AnnotatedDiscriminatorColumn discriminatorColumn = processJoinedDiscriminatorProperties( state );
@ -936,8 +945,7 @@ public class EntityBinder {
rootClass.setPolymorphic( true ); rootClass.setPolymorphic( true );
final String rootEntityName = rootClass.getEntityName(); final String rootEntityName = rootClass.getEntityName();
LOG.tracev( "Setting discriminator for entity {0}", rootEntityName); LOG.tracev( "Setting discriminator for entity {0}", rootEntityName);
context.getMetadataCollector() getMetadataCollector().addSecondPass( new NullableDiscriminatorColumnSecondPass( rootEntityName ) );
.addSecondPass( new NullableDiscriminatorColumnSecondPass( rootEntityName ) );
} }
} }
@ -945,10 +953,13 @@ public class EntityBinder {
* Process all discriminator-related metadata per rules for "single table" inheritance * Process all discriminator-related metadata per rules for "single table" inheritance
*/ */
private AnnotatedDiscriminatorColumn processSingleTableDiscriminatorProperties(InheritanceState inheritanceState) { private AnnotatedDiscriminatorColumn processSingleTableDiscriminatorProperties(InheritanceState inheritanceState) {
final DiscriminatorColumn discriminatorColumn = annotatedClass.getAnnotationUsage( DiscriminatorColumn.class, getSourceModelContext() ); final DiscriminatorColumn discriminatorColumn =
final DiscriminatorFormula discriminatorFormula = getOverridableAnnotation( annotatedClass, DiscriminatorFormula.class, context ); annotatedClass.getAnnotationUsage( DiscriminatorColumn.class, getSourceModelContext() );
final DiscriminatorFormula discriminatorFormula =
getOverridableAnnotation( annotatedClass, DiscriminatorFormula.class, context );
if ( !inheritanceState.hasParents() || annotatedClass.hasAnnotationUsage( Inheritance.class, getSourceModelContext() ) ) { if ( !inheritanceState.hasParents()
|| annotatedClass.hasAnnotationUsage( Inheritance.class, getSourceModelContext() ) ) {
return buildDiscriminatorColumn( return buildDiscriminatorColumn(
discriminatorColumn, discriminatorColumn,
discriminatorFormula, discriminatorFormula,
@ -982,8 +993,10 @@ public class EntityBinder {
+ "' has 'JOINED' inheritance and is annotated '@DiscriminatorFormula'" ); + "' has 'JOINED' inheritance and is annotated '@DiscriminatorFormula'" );
} }
final DiscriminatorColumn discriminatorColumn = annotatedClass.getAnnotationUsage( DiscriminatorColumn.class, getSourceModelContext() ); final DiscriminatorColumn discriminatorColumn =
if ( !inheritanceState.hasParents() || annotatedClass.hasAnnotationUsage( Inheritance.class, getSourceModelContext() ) ) { annotatedClass.getAnnotationUsage( DiscriminatorColumn.class, getSourceModelContext() );
if ( !inheritanceState.hasParents()
|| annotatedClass.hasAnnotationUsage( Inheritance.class, getSourceModelContext() ) ) {
return useDiscriminatorColumnForJoined( discriminatorColumn ) return useDiscriminatorColumnForJoined( discriminatorColumn )
? buildDiscriminatorColumn( discriminatorColumn, null, null, DEFAULT_DISCRIMINATOR_COLUMN_NAME, context ) ? buildDiscriminatorColumn( discriminatorColumn, null, null, DEFAULT_DISCRIMINATOR_COLUMN_NAME, context )
: null; : null;
@ -1009,14 +1022,14 @@ public class EntityBinder {
*/ */
private boolean useDiscriminatorColumnForJoined(DiscriminatorColumn discriminatorColumn) { private boolean useDiscriminatorColumnForJoined(DiscriminatorColumn discriminatorColumn) {
if ( discriminatorColumn != null ) { if ( discriminatorColumn != null ) {
boolean ignore = context.getBuildingOptions().ignoreExplicitDiscriminatorsForJoinedInheritance(); final boolean ignore = context.getBuildingOptions().ignoreExplicitDiscriminatorsForJoinedInheritance();
if ( ignore ) { if ( ignore ) {
LOG.debugf( "Ignoring explicit @DiscriminatorColumn annotation on: %s", annotatedClass.getName() ); LOG.debugf( "Ignoring explicit @DiscriminatorColumn annotation on: %s", annotatedClass.getName() );
} }
return !ignore; return !ignore;
} }
else { else {
boolean createImplicit = context.getBuildingOptions().createImplicitDiscriminatorsForJoinedInheritance(); final boolean createImplicit = context.getBuildingOptions().createImplicitDiscriminatorsForJoinedInheritance();
if ( createImplicit ) { if ( createImplicit ) {
LOG.debugf( "Inferring implicit @DiscriminatorColumn using defaults for: %s", annotatedClass.getName() ); LOG.debugf( "Inferring implicit @DiscriminatorColumn using defaults for: %s", annotatedClass.getName() );
} }
@ -1121,9 +1134,11 @@ public class EntityBinder {
final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns(); final AnnotatedJoinColumns joinColumns = new AnnotatedJoinColumns();
joinColumns.setBuildingContext( context ); joinColumns.setBuildingContext( context );
final SourceModelBuildingContext sourceModelContext = context.getMetadataCollector().getSourceModelBuildingContext(); final SourceModelBuildingContext sourceModelContext =
context.getMetadataCollector().getSourceModelBuildingContext();
final PrimaryKeyJoinColumns primaryKeyJoinColumns = clazzToProcess.getAnnotationUsage( PrimaryKeyJoinColumns.class, sourceModelContext ); final PrimaryKeyJoinColumns primaryKeyJoinColumns =
clazzToProcess.getAnnotationUsage( PrimaryKeyJoinColumns.class, sourceModelContext );
if ( primaryKeyJoinColumns != null ) { if ( primaryKeyJoinColumns != null ) {
final PrimaryKeyJoinColumn[] columns = primaryKeyJoinColumns.value(); final PrimaryKeyJoinColumn[] columns = primaryKeyJoinColumns.value();
if ( !ArrayHelper.isEmpty( columns ) ) { if ( !ArrayHelper.isEmpty( columns ) ) {
@ -1138,7 +1153,8 @@ public class EntityBinder {
} }
} }
else { else {
final PrimaryKeyJoinColumn columnAnnotation = clazzToProcess.getAnnotationUsage( PrimaryKeyJoinColumn.class, sourceModelContext ); final PrimaryKeyJoinColumn columnAnnotation =
clazzToProcess.getAnnotationUsage( PrimaryKeyJoinColumn.class, sourceModelContext );
buildInheritanceJoinColumn( buildInheritanceJoinColumn(
columnAnnotation, columnAnnotation,
null, null,
@ -1171,8 +1187,9 @@ public class EntityBinder {
return null; return null;
} }
else { else {
final PersistentClass superEntity = context.getMetadataCollector() final PersistentClass superEntity =
.getEntityBinding( superState.getClassDetails().getName() ); context.getMetadataCollector()
.getEntityBinding( superState.getClassDetails().getName() );
//check if superclass is not a potential persistent class //check if superclass is not a potential persistent class
if ( superEntity == null && inheritanceState.hasParents() ) { if ( superEntity == null && inheritanceState.hasParents() ) {
throw new AssertionFailure( "Subclass has to be bound after its parent class: " throw new AssertionFailure( "Subclass has to be bound after its parent class: "
@ -1185,7 +1202,8 @@ public class EntityBinder {
/** /**
* See {@link JpaEventListener} for a better (?) alternative * See {@link JpaEventListener} for a better (?) alternative
*/ */
private static void bindCallbacks(ClassDetails entityClass, PersistentClass persistentClass, MetadataBuildingContext context) { private static void bindCallbacks(
ClassDetails entityClass, PersistentClass persistentClass, MetadataBuildingContext context) {
for ( CallbackType callbackType : CallbackType.values() ) { for ( CallbackType callbackType : CallbackType.values() ) {
persistentClass.addCallbackDefinitions( CallbackDefinitionResolver.resolveEntityCallbacks( persistentClass.addCallbackDefinitions( CallbackDefinitionResolver.resolveEntityCallbacks(
context, context,
@ -1249,22 +1267,27 @@ public class EntityBinder {
} }
private void bindRowManagement() { private void bindRowManagement() {
final DynamicInsert dynamicInsertAnn = annotatedClass.getAnnotationUsage( DynamicInsert.class, getSourceModelContext() ); final DynamicInsert dynamicInsertAnn =
annotatedClass.getAnnotationUsage( DynamicInsert.class, getSourceModelContext() );
persistentClass.setDynamicInsert( dynamicInsertAnn != null ); persistentClass.setDynamicInsert( dynamicInsertAnn != null );
final DynamicUpdate dynamicUpdateAnn = annotatedClass.getAnnotationUsage( DynamicUpdate.class, getSourceModelContext() ); final DynamicUpdate dynamicUpdateAnn =
annotatedClass.getAnnotationUsage( DynamicUpdate.class, getSourceModelContext() );
persistentClass.setDynamicUpdate( dynamicUpdateAnn != null ); persistentClass.setDynamicUpdate( dynamicUpdateAnn != null );
if ( persistentClass.useDynamicInsert() && annotatedClass.hasAnnotationUsage( SQLInsert.class, getSourceModelContext() ) ) { if ( persistentClass.useDynamicInsert()
&& annotatedClass.hasAnnotationUsage( SQLInsert.class, getSourceModelContext() ) ) {
throw new AnnotationException( "Entity '" + name + "' is annotated both '@DynamicInsert' and '@SQLInsert'" ); throw new AnnotationException( "Entity '" + name + "' is annotated both '@DynamicInsert' and '@SQLInsert'" );
} }
if ( persistentClass.useDynamicUpdate() && annotatedClass.hasAnnotationUsage( SQLUpdate.class, getSourceModelContext() ) ) { if ( persistentClass.useDynamicUpdate()
&& annotatedClass.hasAnnotationUsage( SQLUpdate.class, getSourceModelContext() ) ) {
throw new AnnotationException( "Entity '" + name + "' is annotated both '@DynamicUpdate' and '@SQLUpdate'" ); throw new AnnotationException( "Entity '" + name + "' is annotated both '@DynamicUpdate' and '@SQLUpdate'" );
} }
} }
private void bindOptimisticLocking() { private void bindOptimisticLocking() {
final OptimisticLocking optimisticLockingAnn = annotatedClass.getAnnotationUsage( OptimisticLocking.class, getSourceModelContext() ); final OptimisticLocking optimisticLockingAnn =
annotatedClass.getAnnotationUsage( OptimisticLocking.class, getSourceModelContext() );
persistentClass.setOptimisticLockStyle( fromLockType( optimisticLockingAnn == null persistentClass.setOptimisticLockStyle( fromLockType( optimisticLockingAnn == null
? OptimisticLockType.VERSION ? OptimisticLockType.VERSION
: optimisticLockingAnn.type() ) ); : optimisticLockingAnn.type() ) );
@ -1347,10 +1370,11 @@ public class EntityBinder {
private void registerImportName() { private void registerImportName() {
LOG.debugf( "Import with entity name %s", name ); LOG.debugf( "Import with entity name %s", name );
try { try {
context.getMetadataCollector().addImport( name, persistentClass.getEntityName() ); final InFlightMetadataCollector metadataCollector = getMetadataCollector();
metadataCollector.addImport( name, persistentClass.getEntityName() );
final String entityName = persistentClass.getEntityName(); final String entityName = persistentClass.getEntityName();
if ( !entityName.equals( name ) ) { if ( !entityName.equals( name ) ) {
context.getMetadataCollector().addImport( entityName, entityName ); metadataCollector.addImport( entityName, entityName );
} }
} }
catch (MappingException me) { catch (MappingException me) {
@ -1461,12 +1485,10 @@ public class EntityBinder {
// - if so, we return the matched override // - if so, we return the matched override
// - if not, we return the normal SQLInsert (if one) // - if not, we return the normal SQLInsert (if one)
final Class<Annotation> overrideAnnotation = getOverrideAnnotation( annotationType ); final Class<Annotation> overrideAnnotation = getOverrideAnnotation( annotationType );
final Annotation[] dialectOverrides = annotatedClass.getRepeatedAnnotationUsages( final Annotation[] dialectOverrides =
overrideAnnotation, annotatedClass.getRepeatedAnnotationUsages( overrideAnnotation, getSourceModelContext() );
getSourceModelContext()
);
if ( isNotEmpty( dialectOverrides ) ) { if ( isNotEmpty( dialectOverrides ) ) {
final Dialect dialect = context.getMetadataCollector().getDatabase().getDialect(); final Dialect dialect = getMetadataCollector().getDatabase().getDialect();
for ( int i = 0; i < dialectOverrides.length; i++ ) { for ( int i = 0; i < dialectOverrides.length; i++ ) {
//noinspection unchecked //noinspection unchecked
final DialectOverrider<A> dialectOverride = (DialectOverrider<A>) dialectOverrides[i]; final DialectOverrider<A> dialectOverride = (DialectOverrider<A>) dialectOverrides[i];
@ -1507,7 +1529,7 @@ public class EntityBinder {
} }
private String getDefaultFilterCondition(String filterName) { private String getDefaultFilterCondition(String filterName) {
final FilterDefinition definition = context.getMetadataCollector().getFilterDefinition( filterName ); final FilterDefinition definition = getMetadataCollector().getFilterDefinition( filterName );
if ( definition == null ) { if ( definition == null ) {
throw new AnnotationException( "Entity '" + name throw new AnnotationException( "Entity '" + name
+ "' has a '@Filter' for an undefined filter named '" + filterName + "'" ); + "' has a '@Filter' for an undefined filter named '" + filterName + "'" );
@ -1523,16 +1545,14 @@ public class EntityBinder {
private void bindSynchronize() { private void bindSynchronize() {
final Synchronize synchronize = annotatedClass.getAnnotationUsage( Synchronize.class, getSourceModelContext() ); final Synchronize synchronize = annotatedClass.getAnnotationUsage( Synchronize.class, getSourceModelContext() );
if ( synchronize == null ) { if ( synchronize != null ) {
return; final JdbcEnvironment jdbcEnvironment = getMetadataCollector().getDatabase().getJdbcEnvironment();
} final boolean logical = synchronize.logical();
final String[] tableNames = synchronize.value();
final JdbcEnvironment jdbcEnvironment = context.getMetadataCollector().getDatabase().getJdbcEnvironment(); for ( String tableName : tableNames ) {
final boolean logical = synchronize.logical(); final String physicalName = logical ? toPhysicalName( jdbcEnvironment, tableName ) : tableName;
final String[] tableNames = synchronize.value(); persistentClass.addSynchronizedTable( physicalName );
for ( String tableName : tableNames ) { }
String physicalName = logical ? toPhysicalName( jdbcEnvironment, tableName ) : tableName;
persistentClass.addSynchronizedTable( physicalName );
} }
} }
@ -1553,16 +1573,16 @@ public class EntityBinder {
} }
private void processNamedEntityGraph(NamedEntityGraph annotation) { private void processNamedEntityGraph(NamedEntityGraph annotation) {
if ( annotation == null ) { if ( annotation != null ) {
return; getMetadataCollector()
.addNamedEntityGraph( new NamedEntityGraphDefinition( annotation, name,
persistentClass.getEntityName() ) );
} }
context.getMetadataCollector().addNamedEntityGraph(
new NamedEntityGraphDefinition( annotation, name, persistentClass.getEntityName() )
);
} }
public void bindDiscriminatorValue() { public void bindDiscriminatorValue() {
final DiscriminatorValue discriminatorValueAnn = annotatedClass.getAnnotationUsage( DiscriminatorValue.class, getSourceModelContext() ); final DiscriminatorValue discriminatorValueAnn =
annotatedClass.getAnnotationUsage( DiscriminatorValue.class, getSourceModelContext() );
final String discriminatorValue = discriminatorValueAnn != null final String discriminatorValue = discriminatorValueAnn != null
? discriminatorValueAnn.value() ? discriminatorValueAnn.value()
: null; : null;
@ -1594,7 +1614,8 @@ public class EntityBinder {
} }
public void bindConcreteProxy() { public void bindConcreteProxy() {
final ConcreteProxy annotationUsage = annotatedClass.getAnnotationUsage( ConcreteProxy.class, getSourceModelContext() ); final ConcreteProxy annotationUsage =
annotatedClass.getAnnotationUsage( ConcreteProxy.class, getSourceModelContext() );
if ( annotationUsage != null ) { if ( annotationUsage != null ) {
if ( persistentClass.getSuperclass() != null ) { if ( persistentClass.getSuperclass() != null ) {
throw new AnnotationException( "Entity class '" + persistentClass.getClassName() throw new AnnotationException( "Entity class '" + persistentClass.getClassName()
@ -1617,7 +1638,8 @@ public class EntityBinder {
private void bindNaturalIdCache() { private void bindNaturalIdCache() {
naturalIdCacheRegion = null; naturalIdCacheRegion = null;
final NaturalIdCache naturalIdCacheAnn = annotatedClass.getAnnotationUsage( NaturalIdCache.class, getSourceModelContext() ); final NaturalIdCache naturalIdCacheAnn =
annotatedClass.getAnnotationUsage( NaturalIdCache.class, getSourceModelContext() );
if ( naturalIdCacheAnn == null ) { if ( naturalIdCacheAnn == null ) {
return; return;
} }
@ -1686,7 +1708,8 @@ public class EntityBinder {
cacheRegion = effectiveCache.region(); cacheRegion = effectiveCache.region();
cacheLazyProperty = isCacheLazy( effectiveCache, annotatedClass ); cacheLazyProperty = isCacheLazy( effectiveCache, annotatedClass );
final QueryCacheLayout queryCache = annotatedClass.getAnnotationUsage( QueryCacheLayout.class, getSourceModelContext() ); final QueryCacheLayout queryCache =
annotatedClass.getAnnotationUsage( QueryCacheLayout.class, getSourceModelContext() );
queryCacheLayout = queryCache == null ? null : queryCache.layout(); queryCacheLayout = queryCache == null ? null : queryCache.layout();
} }
@ -1722,7 +1745,8 @@ public class EntityBinder {
} }
private static Cache buildCacheMock(ClassDetails classDetails, MetadataBuildingContext context) { private static Cache buildCacheMock(ClassDetails classDetails, MetadataBuildingContext context) {
final CacheAnnotation cacheUsage = HibernateAnnotations.CACHE.createUsage( context.getMetadataCollector().getSourceModelBuildingContext() ); final CacheAnnotation cacheUsage =
HibernateAnnotations.CACHE.createUsage( context.getMetadataCollector().getSourceModelBuildingContext() );
cacheUsage.region( classDetails.getName() ); cacheUsage.region( classDetails.getName() );
cacheUsage.usage( determineCacheConcurrencyStrategy( context ) ); cacheUsage.usage( determineCacheConcurrencyStrategy( context ) );
return cacheUsage; return cacheUsage;
@ -1802,7 +1826,7 @@ public class EntityBinder {
); );
} }
final InFlightMetadataCollector collector = context.getMetadataCollector(); final InFlightMetadataCollector collector = getMetadataCollector();
final InFlightMetadataCollector.EntityTableXref superTableXref = final InFlightMetadataCollector.EntityTableXref superTableXref =
collector.getEntityTableXref( entityName ); collector.getEntityTableXref( entityName );
final Table primaryTable = superTableXref.getPrimaryTable(); final Table primaryTable = superTableXref.getPrimaryTable();
@ -1851,12 +1875,11 @@ public class EntityBinder {
// table.setComment( comment.value() ); // table.setComment( comment.value() );
// } // }
context.getMetadataCollector() getMetadataCollector().addEntityTableXref( entityName, logicalName, table, denormalizedSuperTableXref );
.addEntityTableXref( entityName, logicalName, table, denormalizedSuperTableXref );
if ( persistentClass instanceof TableOwner ) { if ( persistentClass instanceof TableOwner tableOwner ) {
LOG.debugf( "Bind entity %s on table %s", entityName, table.getName() ); LOG.debugf( "Bind entity %s on table %s", entityName, table.getName() );
( (TableOwner) persistentClass ).setTable( table ); tableOwner.setTable( table );
} }
else { else {
throw new AssertionFailure( "binding a table for a subclass" ); throw new AssertionFailure( "binding a table for a subclass" );
@ -2109,11 +2132,8 @@ public class EntityBinder {
return new QualifiedTableName( return new QualifiedTableName(
toIdentifier( catalog ), toIdentifier( catalog ),
toIdentifier( schema ), toIdentifier( schema ),
context.getMetadataCollector() getMetadataCollector().getDatabase().getJdbcEnvironment()
.getDatabase() .getIdentifierHelper().toIdentifier( name )
.getJdbcEnvironment()
.getIdentifierHelper()
.toIdentifier( name )
); );
} }
@ -2129,7 +2149,7 @@ public class EntityBinder {
final String entityName = persistentClass.getEntityName(); final String entityName = persistentClass.getEntityName();
final InFlightMetadataCollector.EntityTableXref tableXref final InFlightMetadataCollector.EntityTableXref tableXref
= context.getMetadataCollector().getEntityTableXref( entityName ); = getMetadataCollector().getEntityTableXref( entityName );
assert tableXref != null : "Could not locate EntityTableXref for entity [" + entityName + "]"; assert tableXref != null : "Could not locate EntityTableXref for entity [" + entityName + "]";
tableXref.addSecondaryTable( logicalName, join ); tableXref.addSecondaryTable( logicalName, join );
@ -2278,7 +2298,7 @@ public class EntityBinder {
ClassDetails classToProcess = annotatedClass.getSuperClass(); ClassDetails classToProcess = annotatedClass.getSuperClass();
while ( classToProcess != null ) { while ( classToProcess != null ) {
final AnnotatedClassType classType = context.getMetadataCollector().getClassType( classToProcess ); final AnnotatedClassType classType = getMetadataCollector().getClassType( classToProcess );
if ( classType == MAPPED_SUPERCLASS ) { if ( classType == MAPPED_SUPERCLASS ) {
bindFilters( classToProcess ); bindFilters( classToProcess );
} }

View File

@ -21,6 +21,7 @@ import org.hibernate.mapping.SimpleValue;
import org.hibernate.resource.beans.spi.ManagedBean; import org.hibernate.resource.beans.spi.ManagedBean;
import org.hibernate.usertype.UserCollectionType; import org.hibernate.usertype.UserCollectionType;
import static org.hibernate.boot.model.internal.PropertyHolderBuilder.buildPropertyHolder;
import static org.hibernate.internal.util.StringHelper.qualify; import static org.hibernate.internal.util.StringHelper.qualify;
/** /**
@ -65,14 +66,8 @@ public class ListBinder extends CollectionBinder {
} }
private void bindIndex() { private void bindIndex() {
final PropertyHolder valueHolder = PropertyHolderBuilder.buildPropertyHolder( final PropertyHolder valueHolder =
collection, buildPropertyHolder( collection, getPath(), null, null, propertyHolder, buildingContext );
qualify( collection.getRole(), "key" ),
null,
null,
propertyHolder,
getBuildingContext()
);
if ( !collection.isOneToMany() ) { if ( !collection.isOneToMany() ) {
indexColumn.forceNotNull(); indexColumn.forceNotNull();
@ -94,6 +89,10 @@ public class ListBinder extends CollectionBinder {
createBackref(); createBackref();
} }
private String getPath() {
return qualify( collection.getRole(), "key" );
}
private void createBackref() { private void createBackref() {
if ( collection.isOneToMany() if ( collection.isOneToMany()
&& !collection.getKey().isNullable() && !collection.getKey().isNullable()

View File

@ -291,14 +291,8 @@ public class MapBinder extends CollectionBinder {
private CollectionPropertyHolder buildCollectionPropertyHolder( private CollectionPropertyHolder buildCollectionPropertyHolder(
MemberDetails property, MemberDetails property,
ClassDetails keyClass) { ClassDetails keyClass) {
final CollectionPropertyHolder holder = buildPropertyHolder( final CollectionPropertyHolder holder =
collection, buildPropertyHolder( collection, getPath(), keyClass, property, propertyHolder, buildingContext );
qualify( collection.getRole(), "mapkey" ),
keyClass,
property,
propertyHolder,
buildingContext
);
// 'propertyHolder' is the PropertyHolder for the owner of the collection // 'propertyHolder' is the PropertyHolder for the owner of the collection
// 'holder' is the CollectionPropertyHolder. // 'holder' is the CollectionPropertyHolder.
// 'property' is the collection XProperty // 'property' is the collection XProperty
@ -307,6 +301,10 @@ public class MapBinder extends CollectionBinder {
return holder; return holder;
} }
private String getPath() {
return qualify( collection.getRole(), "mapkey" );
}
private void handleForeignKey(MemberDetails property, ManyToOne element) { private void handleForeignKey(MemberDetails property, ManyToOne element) {
final ForeignKey foreignKey = getMapKeyForeignKey( property ); final ForeignKey foreignKey = getMapKeyForeignKey( property );
if ( foreignKey != null ) { if ( foreignKey != null ) {
@ -472,8 +470,8 @@ public class MapBinder extends CollectionBinder {
Collection collection, Collection collection,
PersistentClass associatedClass, PersistentClass associatedClass,
PersistentClass targetPropertyPersistentClass) { PersistentClass targetPropertyPersistentClass) {
if ( value instanceof Component ) { if ( value instanceof Component component ) {
return createIndexComponent( collection, associatedClass, (Component) value ); return createIndexComponent( collection, associatedClass, component );
} }
else { else {
// HHH-11005 - only if we are @OneToMany and location of map key property is // HHH-11005 - only if we are @OneToMany and location of map key property is
@ -481,11 +479,11 @@ public class MapBinder extends CollectionBinder {
final Table mapKeyTable = !associatedClass.equals( targetPropertyPersistentClass ) final Table mapKeyTable = !associatedClass.equals( targetPropertyPersistentClass )
? targetPropertyPersistentClass.getTable() ? targetPropertyPersistentClass.getTable()
: associatedClass.getTable(); : associatedClass.getTable();
if ( value instanceof BasicValue ) { if ( value instanceof BasicValue basicValue ) {
return createDependantBasicValue( mapKeyTable, (BasicValue) value ); return createDependantBasicValue( mapKeyTable, basicValue );
} }
else if ( value instanceof SimpleValue ) { else if ( value instanceof SimpleValue simpleValue ) {
return createTargetValue( mapKeyTable, (SimpleValue) value ); return createTargetValue( mapKeyTable, simpleValue );
} }
else { else {
throw new AssertionFailure( "Unknown type encountered for map key: " + value.getClass() ); throw new AssertionFailure( "Unknown type encountered for map key: " + value.getClass() );
@ -526,11 +524,11 @@ public class MapBinder extends CollectionBinder {
} }
private static void addSelectable(SimpleValue targetValue, Selectable selectable) { private static void addSelectable(SimpleValue targetValue, Selectable selectable) {
if ( selectable instanceof Column ) { if ( selectable instanceof Column column ) {
targetValue.addColumn( ( (Column) selectable).clone(), false, false ); targetValue.addColumn( column.clone(), false, false );
} }
else if ( selectable instanceof Formula ) { else if ( selectable instanceof Formula formula ) {
targetValue.addFormula( new Formula( ( (Formula) selectable).getFormula() ) ); targetValue.addFormula( new Formula( formula.getFormula() ) );
} }
else { else {
throw new AssertionFailure( "Unknown element in column iterator: " + selectable.getClass() ); throw new AssertionFailure( "Unknown element in column iterator: " + selectable.getClass() );

View File

@ -60,8 +60,8 @@ class NaturalIdBinder {
final Property property = columns.resolveProperty(); final Property property = columns.resolveProperty();
if ( property.isComposite() ) { if ( property.isComposite() ) {
for ( Selectable selectable : property.getValue().getSelectables() ) { for ( Selectable selectable : property.getValue().getSelectables() ) {
if ( selectable instanceof org.hibernate.mapping.Column) { if ( selectable instanceof org.hibernate.mapping.Column column) {
uniqueKey.addColumn( tableColumn( (org.hibernate.mapping.Column) selectable, table, collector ) ); uniqueKey.addColumn( tableColumn( column, table, collector ) );
} }
} }
} }

View File

@ -442,14 +442,14 @@ public class PropertyBinder {
} }
private void handleLob(Property property) { private void handleLob(Property property) {
if ( this.memberDetails != null ) { if ( memberDetails != null ) {
// HHH-4635 -- needed for dialect-specific property ordering // HHH-4635 -- needed for dialect-specific property ordering
property.setLob( this.memberDetails.hasDirectAnnotationUsage( Lob.class ) ); property.setLob( memberDetails.hasDirectAnnotationUsage( Lob.class ) );
} }
} }
private void handleMutability(Property property) { private void handleMutability(Property property) {
if ( this.memberDetails != null && this.memberDetails.hasDirectAnnotationUsage( Immutable.class ) ) { if ( memberDetails != null && memberDetails.hasDirectAnnotationUsage( Immutable.class ) ) {
updatable = false; updatable = false;
} }
property.setInsertable( insertable ); property.setInsertable( insertable );
@ -457,8 +457,8 @@ public class PropertyBinder {
} }
private void handleOptional(Property property) { private void handleOptional(Property property) {
if ( this.memberDetails != null ) { if ( memberDetails != null ) {
property.setOptional( !isId && isOptional( this.memberDetails, this.holder ) ); property.setOptional( !isId && isOptional( memberDetails, holder ) );
if ( property.isOptional() ) { if ( property.isOptional() ) {
final OptionalDeterminationSecondPass secondPass = persistentClasses -> { final OptionalDeterminationSecondPass secondPass = persistentClasses -> {
// Defer determining whether a property and its columns are nullable, // Defer determining whether a property and its columns are nullable,
@ -487,8 +487,8 @@ public class PropertyBinder {
} }
private void handleNaturalId(Property property) { private void handleNaturalId(Property property) {
if ( this.memberDetails != null && entityBinder != null ) { if ( memberDetails != null && entityBinder != null ) {
final NaturalId naturalId = this.memberDetails.getDirectAnnotationUsage( NaturalId.class ); final NaturalId naturalId = memberDetails.getDirectAnnotationUsage( NaturalId.class );
if ( naturalId != null ) { if ( naturalId != null ) {
if ( !entityBinder.isRootEntity() ) { if ( !entityBinder.isRootEntity() ) {
throw new AnnotationException( "Property '" + qualify( holder.getPath(), name ) throw new AnnotationException( "Property '" + qualify( holder.getPath(), name )
@ -505,11 +505,11 @@ public class PropertyBinder {
private void inferOptimisticLocking(Property property) { private void inferOptimisticLocking(Property property) {
// this is already handled for collections in CollectionBinder... // this is already handled for collections in CollectionBinder...
if ( value instanceof Collection ) { if ( value instanceof Collection collection ) {
property.setOptimisticLocked( ((Collection) value).isOptimisticLocked() ); property.setOptimisticLocked( collection.isOptimisticLocked() );
} }
else if ( this.memberDetails != null && this.memberDetails.hasDirectAnnotationUsage( OptimisticLock.class ) ) { else if ( memberDetails != null && memberDetails.hasDirectAnnotationUsage( OptimisticLock.class ) ) {
final OptimisticLock optimisticLock = this.memberDetails.getDirectAnnotationUsage( OptimisticLock.class ); final OptimisticLock optimisticLock = memberDetails.getDirectAnnotationUsage( OptimisticLock.class );
final boolean excluded = optimisticLock.excluded(); final boolean excluded = optimisticLock.excluded();
validateOptimisticLock( excluded ); validateOptimisticLock( excluded );
property.setOptimisticLocked( !excluded ); property.setOptimisticLocked( !excluded );

View File

@ -533,7 +533,7 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
@Override @Override
public boolean isSame(Value other) { public boolean isSame(Value other) {
return this == other return this == other
|| other instanceof Collection && isSame( (Collection) other ); || other instanceof Collection collection && isSame( collection );
} }
protected static boolean isSame(Value v1, Value v2) { protected static boolean isSame(Value v1, Value v2) {
@ -770,8 +770,8 @@ public abstract class Collection implements Fetchable, Value, Filterable, SoftDe
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
public void setTypeParameters(java.util.Map typeParameters) { public void setTypeParameters(java.util.Map typeParameters) {
if ( typeParameters instanceof Properties ) { if ( typeParameters instanceof Properties properties ) {
this.typeParameters = (Properties) typeParameters; this.typeParameters = properties;
} }
else { else {
this.typeParameters = new Properties(); this.typeParameters = new Properties();

View File

@ -40,9 +40,11 @@ public abstract class IndexedCollection extends Collection {
public Value getIndex() { public Value getIndex() {
return index; return index;
} }
public void setIndex(Value index) { public void setIndex(Value index) {
this.index = index; this.index = index;
} }
public final boolean isIndexed() { public final boolean isIndexed() {
return true; return true;
} }
@ -53,18 +55,18 @@ public abstract class IndexedCollection extends Collection {
@Override @Override
public boolean isSame(Collection other) { public boolean isSame(Collection other) {
return other instanceof IndexedCollection return other instanceof IndexedCollection indexedCollection
&& isSame( (IndexedCollection) other ); && isSame( indexedCollection );
} }
public boolean isSame(IndexedCollection other) { public boolean isSame(IndexedCollection other) {
return super.isSame( other ) return super.isSame( other )
&& isSame( index, other.index ); && isSame( index, other.index );
} }
void createPrimaryKey() { void createPrimaryKey() {
if ( !isOneToMany() ) { if ( !isOneToMany() ) {
PrimaryKey pk = new PrimaryKey( getCollectionTable() ); final PrimaryKey pk = new PrimaryKey( getCollectionTable() );
pk.addColumns( getKey() ); pk.addColumns( getKey() );
// index should be last column listed // index should be last column listed
@ -94,6 +96,7 @@ public abstract class IndexedCollection extends Collection {
// } // }
} }
@Deprecated
public void validate(Mapping mapping) throws MappingException { public void validate(Mapping mapping) throws MappingException {
validate( (MappingContext) mapping); validate( (MappingContext) mapping);
} }