From 2b1ef411d86a1e6db3a09738b462a60685c88b5a Mon Sep 17 00:00:00 2001 From: Gavin King Date: Wed, 29 Dec 2021 20:43:41 +0100 Subject: [PATCH 1/2] introduce a @DialectOverride annotation This allows the use of native SQL in annotations of portable programs. We've needed something like this for a long time. --- .../userguide/schema/ColumnDefaultTest.java | 10 ++++- .../java/org/hibernate/annotations/Check.java | 6 +++ .../hibernate/annotations/ColumnDefault.java | 6 +++ .../annotations/DialectOverride.java | 44 +++++++++++++++++++ .../annotations/DiscriminatorFormula.java | 6 +++ .../org/hibernate/annotations/Filter.java | 7 +++ .../org/hibernate/annotations/FilterDef.java | 7 +++ .../org/hibernate/annotations/Formula.java | 6 +++ .../annotations/GeneratedColumn.java | 6 +++ .../hibernate/annotations/JoinFormula.java | 7 +++ .../org/hibernate/annotations/OrderBy.java | 6 +++ .../java/org/hibernate/annotations/Where.java | 6 +++ .../org/hibernate/cfg/AnnotatedColumn.java | 24 ++++++---- .../cfg/AnnotatedDiscriminatorColumn.java | 6 ++- .../hibernate/cfg/AnnotatedJoinColumn.java | 8 +++- .../org/hibernate/cfg/AnnotationBinder.java | 26 +++++++++-- .../cfg/annotations/CollectionBinder.java | 35 +++++++-------- .../cfg/annotations/EntityBinder.java | 23 ++++++---- .../main/java/org/hibernate/sql/Template.java | 11 ++--- .../test/mapping/formula/FormulaTests.java | 5 ++- 20 files changed, 202 insertions(+), 53 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/annotations/DialectOverride.java diff --git a/documentation/src/test/java/org/hibernate/userguide/schema/ColumnDefaultTest.java b/documentation/src/test/java/org/hibernate/userguide/schema/ColumnDefaultTest.java index 7635bfc7b765..564cb88c9503 100644 --- a/documentation/src/test/java/org/hibernate/userguide/schema/ColumnDefaultTest.java +++ b/documentation/src/test/java/org/hibernate/userguide/schema/ColumnDefaultTest.java @@ -10,7 +10,10 @@ import jakarta.persistence.Id; import org.hibernate.annotations.ColumnDefault; +import org.hibernate.annotations.DialectOverride; import org.hibernate.annotations.DynamicInsert; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.dialect.HSQLDialect; import org.hibernate.orm.test.jpa.BaseEntityManagerFunctionalTestCase; import org.junit.Test; @@ -57,7 +60,12 @@ public static class Person { @ColumnDefault("'N/A'") private String name; - @ColumnDefault("-1") + @ColumnDefault(value = "-1", + overrides = { + @DialectOverride(dialect = HSQLDialect.class, value = "-1"), + @DialectOverride(dialect = H2Dialect.class, value = "-1*1") + } + ) private Long clientId; //Getter and setters omitted for brevity diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Check.java b/hibernate-core/src/main/java/org/hibernate/annotations/Check.java index 261e871ffaa0..660225cce1d1 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Check.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Check.java @@ -26,4 +26,10 @@ * The check constraints string. */ String constraints(); + /** + * A list of SQL constraints that should be used in the specified dialects. + * + * Overrides the default {@link #constraints()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/ColumnDefault.java b/hibernate-core/src/main/java/org/hibernate/annotations/ColumnDefault.java index 2c02eb3d49c9..2226b1e11648 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/ColumnDefault.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/ColumnDefault.java @@ -37,4 +37,10 @@ * @return a SQL expression that evaluates to the default column value */ String value(); + /** + * A list of SQL expressions that should be used in the specified dialects. + * + * Overrides the default {@link #value()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DialectOverride.java b/hibernate-core/src/main/java/org/hibernate/annotations/DialectOverride.java new file mode 100644 index 000000000000..be92bea0db1c --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/annotations/DialectOverride.java @@ -0,0 +1,44 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.annotations; + +import org.hibernate.dialect.Dialect; + +import java.lang.annotation.Retention; + +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * Defines a SQL expression or fragment of SQL that should be used in a given dialect. + * Allows a portable program to embed unportable native SQL in annotations. + * + * @see Formula#overrides() + * @see JoinFormula#overrides() + * @see DiscriminatorFormula#overrides() + * @see Check#overrides() + * @see ColumnDefault#overrides() + * @see Filter#overrides() + * @see FilterDef#overrides() + * @see Where#overrides() + * @see OrderBy#overrides() + * + * @author Gavin King + */ +@Retention(RUNTIME) +public @interface DialectOverride { + /** + * The {@link Dialect} to which this override applies. + * + * @return the concrete Java class of the {@code Dialect} + */ + Class dialect(); + + /** + * The SQL expression or SQL fragment that should be used in the specified dialect. + */ + String value(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java b/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java index 11c35275f76d..0cd5c2aa34b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/DiscriminatorFormula.java @@ -30,4 +30,10 @@ * The formula string. */ String value(); + /** + * A list of SQL formulas that should be used in the specified dialects. + * + * Overrides the default {@link #value()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Filter.java b/hibernate-core/src/main/java/org/hibernate/annotations/Filter.java index 811d53db198f..cde1552ede46 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Filter.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Filter.java @@ -48,4 +48,11 @@ * The alias descriptors for injection. */ SqlFragmentAlias[] aliases() default {}; + + /** + * A list of SQL conditions that should be used in the specified dialects. + * + * Overrides the default {@link #condition()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/FilterDef.java b/hibernate-core/src/main/java/org/hibernate/annotations/FilterDef.java index 57ca33632379..2e8b1bac3f1a 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/FilterDef.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/FilterDef.java @@ -37,4 +37,11 @@ * The filter parameter definitions. */ ParamDef[] parameters() default {}; + + /** + * A list of SQL conditions that should be used in the specified dialects. + * + * Overrides the default {@link #defaultCondition()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Formula.java b/hibernate-core/src/main/java/org/hibernate/annotations/Formula.java index 36ffbc4146ae..c5dbd1f0450b 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Formula.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Formula.java @@ -50,4 +50,10 @@ * The formula string. */ String value(); + /** + * A list of SQL formulas that should be used in the specified dialects. + * + * Overrides the default {@link #value()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/GeneratedColumn.java b/hibernate-core/src/main/java/org/hibernate/annotations/GeneratedColumn.java index 5428f33bbafa..e008d3dafea0 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/GeneratedColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/GeneratedColumn.java @@ -34,4 +34,10 @@ * @return the SQL expression that is evaluated to generate the column value. */ String value(); + /** + * A list of SQL expressions that should be used in the specified dialects. + * + * Overrides the default {@link #value()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/JoinFormula.java b/hibernate-core/src/main/java/org/hibernate/annotations/JoinFormula.java index 903536f029e7..3441baa2f488 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/JoinFormula.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/JoinFormula.java @@ -31,4 +31,11 @@ * The column this formula references. */ String referencedColumnName() default ""; + + /** + * A list of SQL formulas that should be used in the specified dialects. + * + * Overrides the default {@link #value()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java b/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java index f14f1120daba..aac1a5bd0240 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/OrderBy.java @@ -44,4 +44,10 @@ * The native SQL expression used to sort the collection elements. */ String clause(); + /** + * A list of SQL ordering expressions that should be used in the specified dialects. + * + * Overrides the default {@link #clause()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/annotations/Where.java b/hibernate-core/src/main/java/org/hibernate/annotations/Where.java index d11468ea56f6..9696070bdaa1 100644 --- a/hibernate-core/src/main/java/org/hibernate/annotations/Where.java +++ b/hibernate-core/src/main/java/org/hibernate/annotations/Where.java @@ -27,4 +27,10 @@ * The where-clause predicate. */ String clause(); + /** + * A list of SQL predicates that should be used in the specified dialects. + * + * Overrides the default {@link #clause()}. + */ + DialectOverride[] overrides() default {}; } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java index bfbbd82b2789..9f367ba4908c 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java @@ -536,7 +536,7 @@ public static AnnotatedColumn[] buildColumnFromAnnotation( AnnotatedColumn[] columns; if ( formulaAnn != null ) { AnnotatedColumn formulaColumn = new AnnotatedColumn(); - formulaColumn.setFormula( formulaAnn.value() ); + formulaColumn.setFormula( getFormulaValue(formulaAnn, context) ); formulaColumn.setImplicit( false ); formulaColumn.setBuildingContext( context ); formulaColumn.setPropertyHolder( propertyHolder ); @@ -614,7 +614,6 @@ public static AnnotatedColumn[] buildColumnFromAnnotation( } AnnotatedColumn column = new AnnotatedColumn(); - column.setImplicit( false ); column.setSqlType( sqlType ); column.setLength( (long) col.length() ); @@ -654,6 +653,18 @@ public static AnnotatedColumn[] buildColumnFromAnnotation( return columns; } + private static String getFormulaValue(org.hibernate.annotations.Formula annotation, MetadataBuildingContext context) { + return annotation == null ? null : AnnotationBinder.dialectValue( annotation.value(), annotation.overrides(), context ); + } + + private static String getColumnDefaultValue(ColumnDefault annotation, MetadataBuildingContext context) { + return annotation == null ? null : AnnotationBinder.dialectValue( annotation.value(), annotation.overrides(), context ); + } + + private static String getGeneratedAsValue(GeneratedColumn annotation, MetadataBuildingContext context) { + return annotation == null ? null : AnnotationBinder.dialectValue( annotation.value(), annotation.overrides(), context ); + } + private void applyColumnDefault(PropertyData inferredData, int length) { final XProperty xProperty = inferredData.getProperty(); if ( xProperty != null ) { @@ -662,14 +673,9 @@ private void applyColumnDefault(PropertyData inferredData, int length) { if (length!=1) { throw new MappingException("@ColumnDefault may only be applied to single-column mappings"); } - setDefaultValue( columnDefaultAnn.value() ); + setDefaultValue( getColumnDefaultValue( columnDefaultAnn, context ) ); } } - else { - LOG.trace( - "Could not perform @ColumnDefault lookup as 'PropertyData' did not give access to XProperty" - ); - } } private void applyGeneratedAs(PropertyData inferredData, int length) { @@ -680,7 +686,7 @@ private void applyGeneratedAs(PropertyData inferredData, int length) { if (length!=1) { throw new MappingException("@GeneratedColumn may only be applied to single-column mappings"); } - setGeneratedAs( generatedAnn.value() ); + setGeneratedAs( getGeneratedAsValue( generatedAnn, context ) ); } } else { diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java index a413e0ef5f46..5fe5e044b8ef 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java @@ -41,6 +41,10 @@ public void setDiscriminatorTypeName(String discriminatorTypeName) { this.discriminatorTypeName = discriminatorTypeName; } + private static String getFormulaValue(DiscriminatorFormula annotation, MetadataBuildingContext context) { + return annotation == null ? null : AnnotationBinder.dialectValue( annotation.value(), annotation.overrides(), context ); + } + public static AnnotatedDiscriminatorColumn buildDiscriminatorColumn( DiscriminatorType type, DiscriminatorColumn discAnn, DiscriminatorFormula discFormulaAnn, @@ -50,7 +54,7 @@ public static AnnotatedDiscriminatorColumn buildDiscriminatorColumn( discriminatorColumn.setImplicit( true ); if ( discFormulaAnn != null ) { discriminatorColumn.setImplicit( false ); - discriminatorColumn.setFormula( discFormulaAnn.value() ); + discriminatorColumn.setFormula( getFormulaValue( discFormulaAnn, context ) ); } else if ( discAnn != null ) { discriminatorColumn.setImplicit( false ); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java index 127599fec430..13538c0ffd10 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java @@ -171,8 +171,8 @@ public static AnnotatedJoinColumn buildJoinFormula( String propertyName, MetadataBuildingContext buildingContext) { AnnotatedJoinColumn formulaColumn = new AnnotatedJoinColumn(); - formulaColumn.setFormula( ann.value() ); - formulaColumn.setReferencedColumn(ann.referencedColumnName()); + formulaColumn.setFormula( getJoinFormulaValue( ann, buildingContext ) ); + formulaColumn.setReferencedColumn( ann.referencedColumnName() ); formulaColumn.setBuildingContext( buildingContext ); formulaColumn.setPropertyHolder( propertyHolder ); formulaColumn.setJoins( joins ); @@ -181,6 +181,10 @@ public static AnnotatedJoinColumn buildJoinFormula( return formulaColumn; } + private static String getJoinFormulaValue(JoinFormula annotation, MetadataBuildingContext context) { + return annotation == null ? null : AnnotationBinder.dialectValue( annotation.value(), annotation.overrides(), context ); + } + public static AnnotatedJoinColumn[] buildJoinColumns( JoinColumn[] anns, Comment comment, diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java index 4650ec357291..6eb78ddecfb7 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotationBinder.java @@ -36,6 +36,7 @@ import org.hibernate.annotations.CollectionTypeRegistrations; import org.hibernate.annotations.Columns; import org.hibernate.annotations.Comment; +import org.hibernate.annotations.DialectOverride; import org.hibernate.annotations.DiscriminatorFormula; import org.hibernate.annotations.DiscriminatorOptions; import org.hibernate.annotations.EmbeddableInstantiatorRegistration; @@ -104,6 +105,7 @@ import org.hibernate.cfg.annotations.QueryBinder; import org.hibernate.cfg.annotations.TableBinder; import org.hibernate.cfg.internal.NullableDiscriminatorColumnSecondPass; +import org.hibernate.dialect.Dialect; import org.hibernate.engine.OptimisticLockStyle; import org.hibernate.engine.spi.FilterDefinition; import org.hibernate.id.IdentifierGenerator; @@ -641,9 +643,7 @@ else if ( InheritanceType.JOINED.equals( inheritanceState.getType() ) ) { if ( inheritanceState.hasTable() ) { Check checkAnn = clazzToProcess.getAnnotation( Check.class ); - String constraints = checkAnn == null - ? null - : checkAnn.constraints(); + String constraints = getCheckConstraints( checkAnn, context ); EntityTableXref denormalizedTableXref = inheritanceState.hasDenormalizedTable() ? context.getMetadataCollector().getEntityTableXref( superEntity.getEntityName() ) @@ -1463,11 +1463,29 @@ private static void bindFilterDef(FilterDef defAnn, MetadataBuildingContext cont ); } - final FilterDefinition def = new FilterDefinition( defAnn.name(), defAnn.defaultCondition(), params ); + final FilterDefinition def = new FilterDefinition( defAnn.name(), getFilterCondition( defAnn, context ), params ); LOG.debugf( "Binding filter definition: %s", def.getFilterName() ); context.getMetadataCollector().addFilterDefinition( def ); } + static String getFilterCondition(FilterDef annotation, MetadataBuildingContext context) { + return annotation == null ? null : dialectValue( annotation.defaultCondition(), annotation.overrides(), context ); + } + + private static String getCheckConstraints(Check annotation, MetadataBuildingContext context) { + return annotation == null ? null : dialectValue( annotation.constraints(), annotation.overrides(), context ); + } + + public static String dialectValue(String defaultValue, DialectOverride[] dialectOverrides, MetadataBuildingContext context) { + Dialect dialect = context.getMetadataCollector().getDatabase().getDialect(); + for ( DialectOverride df: dialectOverrides ) { + if ( df.dialect().isInstance(dialect) ) { + return df.value(); + } + } + return defaultValue; + } + private static void bindCallbacks(XClass entityClass, PersistentClass persistentClass, MetadataBuildingContext context) { ReflectionManager reflectionManager = context.getBootstrapContext().getReflectionManager(); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java index 446c6bc42c02..b29810638f31 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/CollectionBinder.java @@ -839,7 +839,7 @@ else if ( comparatorSort != null ) { // we can only apply the sql-based order by up front. The jpa order by has to wait for second pass if ( sqlOrderBy != null ) { - collection.setOrderBy( sqlOrderBy.clause() ); + collection.setOrderBy( getOrderByClause( sqlOrderBy, buildingContext ) ); } } @@ -893,6 +893,10 @@ private AnnotationException buildIllegalOrderAndSortCombination() { ); } + static String getOrderByClause(OrderBy annotation, MetadataBuildingContext context) { + return annotation == null ? null : AnnotationBinder.dialectValue( annotation.clause(), annotation.overrides(), context ); + } + private AnnotationException buildIllegalSortCombination() { return new AnnotationException( String.format( @@ -1137,7 +1141,7 @@ protected void bindOneToManySecondPass( if ( LOG.isDebugEnabled() ) { LOG.debugf( "Mapping collection: %s -> %s", collection.getRole(), collection.getCollectionTable().getName() ); } - bindFilters( false ); + bindFilters( false, buildingContext ); bindCollectionSecondPass( collection, null, fkJoinColumns, cascadeDeleteEnabled, property, propertyHolder, buildingContext ); if ( !collection.isInverse() && !collection.getKey().isNullable() ) { @@ -1156,18 +1160,18 @@ protected void bindOneToManySecondPass( } - private void bindFilters(boolean hasAssociationTable) { + private void bindFilters(boolean hasAssociationTable, MetadataBuildingContext context) { Filter simpleFilter = property.getAnnotation( Filter.class ); //set filtering //test incompatible choices //if ( StringHelper.isNotEmpty( where ) ) collection.setWhere( where ); if ( simpleFilter != null ) { if ( hasAssociationTable ) { - collection.addManyToManyFilter(simpleFilter.name(), getCondition(simpleFilter), simpleFilter.deduceAliasInjectionPoints(), + collection.addManyToManyFilter(simpleFilter.name(), getCondition(simpleFilter, context), simpleFilter.deduceAliasInjectionPoints(), toAliasTableMap(simpleFilter.aliases()), toAliasEntityMap(simpleFilter.aliases())); } else { - collection.addFilter(simpleFilter.name(), getCondition(simpleFilter), simpleFilter.deduceAliasInjectionPoints(), + collection.addFilter(simpleFilter.name(), getCondition(simpleFilter, context), simpleFilter.deduceAliasInjectionPoints(), toAliasTableMap(simpleFilter.aliases()), toAliasEntityMap(simpleFilter.aliases())); } } @@ -1175,11 +1179,11 @@ private void bindFilters(boolean hasAssociationTable) { if ( filters != null ) { for (Filter filter : filters.value()) { if ( hasAssociationTable ) { - collection.addManyToManyFilter( filter.name(), getCondition(filter), filter.deduceAliasInjectionPoints(), + collection.addManyToManyFilter( filter.name(), getCondition(filter, context), filter.deduceAliasInjectionPoints(), toAliasTableMap(filter.aliases()), toAliasEntityMap(filter.aliases())); } else { - collection.addFilter(filter.name(), getCondition(filter), filter.deduceAliasInjectionPoints(), + collection.addFilter(filter.name(), getCondition(filter, context), filter.deduceAliasInjectionPoints(), toAliasTableMap(filter.aliases()), toAliasEntityMap(filter.aliases())); } } @@ -1234,15 +1238,10 @@ private void bindFilters(boolean hasAssociationTable) { String whereOnClassClause = null; if ( useEntityWhereClauseForCollections && property.getElementClass() != null ) { Where whereOnClass = property.getElementClass().getAnnotation( Where.class ); - if ( whereOnClass != null ) { - whereOnClassClause = whereOnClass.clause(); - } + whereOnClassClause = EntityBinder.getWhereClause( whereOnClass, context ); } Where whereOnCollection = property.getAnnotation( Where.class ); - String whereOnCollectionClause = null; - if ( whereOnCollection != null ) { - whereOnCollectionClause = whereOnCollection.clause(); - } + String whereOnCollectionClause = EntityBinder.getWhereClause( whereOnCollection, context ); final String whereClause = StringHelper.getNonEmptyOrConjunctionIfBothNonEmpty( whereOnClassClause, whereOnCollectionClause @@ -1287,11 +1286,11 @@ private void bindFilters(boolean hasAssociationTable) { // } } - private String getCondition(Filter filter) { + private String getCondition(Filter filter, MetadataBuildingContext context) { //set filtering String name = filter.name(); - String cond = filter.condition(); - return getCondition( cond, name ); + String condition = EntityBinder.getFilterCondition( filter, context ); + return getCondition( condition, name ); } private String getCondition(String cond, String name) { @@ -1654,7 +1653,7 @@ else if ( anyAnn != null ) { associationTableBinder.setJPA2ElementCollection( !isCollectionOfEntities && property.isAnnotationPresent( ElementCollection.class )); collValue.setCollectionTable( associationTableBinder.bind() ); } - bindFilters( isCollectionOfEntities ); + bindFilters( isCollectionOfEntities, buildingContext ); bindCollectionSecondPass( collValue, collectionEntity, joinColumns, cascadeDeleteEnabled, property, propertyHolder, buildingContext ); ManyToOne element = null; diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java index ae8e7ec7ae19..ec36b9484382 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/annotations/EntityBinder.java @@ -365,17 +365,17 @@ public void bindEntity() { for ( Filter filter : filters ) { String filterName = filter.name(); - String cond = filter.condition(); - if ( BinderHelper.isEmptyAnnotationValue( cond ) ) { + String condition = getFilterCondition( filter, context ); + if ( BinderHelper.isEmptyAnnotationValue( condition ) ) { FilterDefinition definition = context.getMetadataCollector().getFilterDefinition( filterName ); - cond = definition == null ? null : definition.getDefaultFilterCondition(); - if ( StringHelper.isEmpty( cond ) ) { + condition = definition == null ? null : definition.getDefaultFilterCondition(); + if ( StringHelper.isEmpty( condition ) ) { throw new AnnotationException( "no filter condition found for filter " + filterName + " in " + this.name ); } } - persistentClass.addFilter(filterName, cond, filter.deduceAliasInjectionPoints(), + persistentClass.addFilter(filterName, condition, filter.deduceAliasInjectionPoints(), toAliasTableMap(filter.aliases()), toAliasEntityMap(filter.aliases())); } LOG.debugf( "Import with entity name %s", name ); @@ -393,6 +393,14 @@ public void bindEntity() { processNamedEntityGraphs(); } + static String getWhereClause(Where annotation, MetadataBuildingContext context) { + return annotation == null ? null : AnnotationBinder.dialectValue( annotation.clause(), annotation.overrides(), context ); + } + + static String getFilterCondition(Filter annotation, MetadataBuildingContext context) { + return annotation == null ? null : AnnotationBinder.dialectValue( annotation.condition(), annotation.overrides(), context ); + } + public PersistentClass getPersistentClass() { return persistentClass; } @@ -475,7 +483,6 @@ public void setBatchSize(BatchSize sizeAnn) { } } - @SuppressWarnings({ "unchecked" }) public void setProxy(Proxy proxy) { if ( proxy != null ) { lazy = proxy.lazy(); @@ -499,9 +506,7 @@ public void setProxy(Proxy proxy) { } public void setWhere(Where whereAnn) { - if ( whereAnn != null ) { - where = whereAnn.clause(); - } + where = getWhereClause( whereAnn, context ); } public void setWrapIdsInEmbeddedComponents(boolean wrapIdsInEmbeddedComponents) { diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Template.java b/hibernate-core/src/main/java/org/hibernate/sql/Template.java index d3bf4d8013f4..214332697de2 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Template.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Template.java @@ -129,19 +129,14 @@ public static String renderWhereStringTemplate(String sqlWhereString, String pla * @param functionRegistry The registry of all sql functions * @return The rendered sql fragment */ - public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect, SqmFunctionRegistry functionRegistry ) { + public static String renderWhereStringTemplate(String sqlWhereString, String placeholder, Dialect dialect, SqmFunctionRegistry functionRegistry) { // IMPL NOTE : The basic process here is to tokenize the incoming string and to iterate over each token // in turn. As we process each token, we set a series of flags used to indicate the type of context in // which the tokens occur. Depending on the state of those flags we decide whether we need to qualify // identifier references. - String symbols = new StringBuilder() - .append( "=> Date: Sun, 9 Jan 2022 12:35:20 +0100 Subject: [PATCH 2/2] fix some warnings in IntelliJ (unnecessary StringBuilder) --- .../org/hibernate/cfg/AnnotatedColumn.java | 9 ++++---- .../cfg/AnnotatedDiscriminatorColumn.java | 9 +++----- .../hibernate/cfg/AnnotatedJoinColumn.java | 11 ++++------ .../java/org/hibernate/cfg/BinderHelper.java | 7 +++--- .../hibernate/cfg/CollectionSecondPass.java | 4 ++-- .../DefaultComponentSafeNamingStrategy.java | 18 ++++----------- .../hibernate/cfg/DefaultNamingStrategy.java | 10 ++++----- .../hibernate/cfg/ImprovedNamingStrategy.java | 10 ++++----- .../PersistenceStandardNamingStrategy.java | 22 +++++++------------ .../hibernate/cfg/PropertyInferredData.java | 7 +----- 10 files changed, 37 insertions(+), 70 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java index 9f367ba4908c..1ae8275349ec 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedColumn.java @@ -836,10 +836,9 @@ void addUniqueKey(String uniqueKeyName, boolean inSecondPass) { @Override public String toString() { - return "Ejb3Column" + "{table=" + getTable() - + ", mappingColumn=" + mappingColumn.getName() - + ", insertable=" + insertable - + ", updatable=" + updatable - + ", unique=" + unique + '}'; + return String.format( + "Ejb3Column{table=%s, mappingColumn=%s, insertable=%s, updatable=%s, unique=%s}", + getTable(), mappingColumn.getName(), insertable, updatable, unique + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java index 5fe5e044b8ef..3d97caa8db30 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedDiscriminatorColumn.java @@ -89,11 +89,8 @@ else if ( DiscriminatorType.STRING.equals( type ) || type == null ) { @Override public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append( "Ejb3DiscriminatorColumn" ); - sb.append( "{logicalColumnName'" ).append( getLogicalColumnName() ).append( '\'' ); - sb.append( ", discriminatorTypeName='" ).append( discriminatorTypeName ).append( '\'' ); - sb.append( '}' ); - return sb.toString(); + return String.format("Ejb3DiscriminatorColumn{logicalColumnName'%s', discriminatorTypeName='%s'}", + getLogicalColumnName(), discriminatorTypeName + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java index 13538c0ffd10..72975bbaba9e 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AnnotatedJoinColumn.java @@ -976,12 +976,9 @@ public void setMappedBy(String entityName, String jpaEntityName, String logicalT @Override public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append( "Ejb3JoinColumn" ); - sb.append( "{logicalColumnName='" ).append( getLogicalColumnName() ).append( '\'' ); - sb.append( ", referencedColumn='" ).append( referencedColumn ).append( '\'' ); - sb.append( ", mappedBy='" ).append( mappedBy ).append( '\'' ); - sb.append( '}' ); - return sb.toString(); + return String.format( + "Ejb3JoinColumn{logicalColumnName='%s', referencedColumn='%s', mappedBy='%s'}", + getLogicalColumnName(), referencedColumn, mappedBy + ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java b/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java index 310f57c3e619..444c064f68b5 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/BinderHelper.java @@ -133,10 +133,9 @@ public static void createSyntheticPropertyReference( * We need to shallow copy those properties to mark them * as non insertable / non updatable */ - StringBuilder propertyNameBuffer = new StringBuilder( "_" ); - propertyNameBuffer.append( associatedClass.getEntityName().replace( '.', '_' ) ); - propertyNameBuffer.append( "_" ).append( columns[0].getPropertyName().replace( '.', '_' ) ); - String syntheticPropertyName = propertyNameBuffer.toString(); + String syntheticPropertyName = + "_" + associatedClass.getEntityName().replace('.', '_') + + "_" + columns[0].getPropertyName().replace('.', '_'); //find properties associated to a certain column Object columnOwner = findColumnOwner( ownerEntity, columns[0].getReferencedColumn(), context ); List properties = findPropertiesByColumns( columnOwner, columns, context ); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java b/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java index 1187aafa8472..be92c9239aa1 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/CollectionSecondPass.java @@ -73,9 +73,9 @@ abstract public void secondPass(Map persistentClasses, Map inheritedMetas) private static String columns(Value val) { StringBuilder columns = new StringBuilder(); - Iterator iter = val.getColumnIterator(); + Iterator iter = val.getColumnIterator(); while ( iter.hasNext() ) { - columns.append( ( (Selectable) iter.next() ).getText() ); + columns.append( iter.next().getText() ); if ( iter.hasNext() ) columns.append( ", " ); } return columns.toString(); diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java index 9ef9c24fdef4..04388bb410a6 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/DefaultComponentSafeNamingStrategy.java @@ -29,14 +29,8 @@ public String collectionTableName( String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable, String propertyName ) { - return tableName( - new StringBuilder( ownerEntityTable ).append( "_" ) - .append( - associatedEntityTable != null ? - associatedEntityTable : - addUnderscores( propertyName ) - ).toString() - ); + String entityTableName = associatedEntityTable != null ? associatedEntityTable : addUnderscores(propertyName); + return tableName( ownerEntityTable + "_" + entityTableName ); } @@ -61,12 +55,8 @@ public String logicalCollectionTableName( return tableName; } else { - return new StringBuilder( ownerEntityTable ).append( "_" ) - .append( - associatedEntityTable != null ? - associatedEntityTable : - propertyName - ).toString(); + String entityTableName = associatedEntityTable != null ? associatedEntityTable : propertyName; + return ownerEntityTable + "_" + entityTableName; } } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java index 815108583de2..907388740f98 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/DefaultNamingStrategy.java @@ -97,12 +97,10 @@ public String logicalCollectionTableName(String tableName, return tableName; } else { - return new StringBuilder(ownerEntityTable).append("_") - .append( - associatedEntityTable != null ? - associatedEntityTable : - StringHelper.unqualify( propertyName ) - ).toString(); + String entityTableName = associatedEntityTable != null + ? associatedEntityTable + : StringHelper.unqualify(propertyName); + return ownerEntityTable + "_" + entityTableName; } } /** diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java index 0268f3cb6eb4..c0a4fbc03be1 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/ImprovedNamingStrategy.java @@ -111,12 +111,10 @@ public String logicalCollectionTableName(String tableName, return tableName; } else { - return new StringBuilder(ownerEntityTable).append("_") - .append( - associatedEntityTable != null ? - associatedEntityTable : - StringHelper.unqualify( propertyName ) - ).toString(); + String entityTableName = associatedEntityTable != null + ? associatedEntityTable + : StringHelper.unqualify(propertyName); + return ownerEntityTable + "_" + entityTableName; } } /** diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceStandardNamingStrategy.java b/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceStandardNamingStrategy.java index 7ee8df675741..96369240c9f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceStandardNamingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceStandardNamingStrategy.java @@ -38,14 +38,10 @@ public String collectionTableName( String ownerEntity, String ownerEntityTable, String associatedEntity, String associatedEntityTable, String propertyName ) { - return tableName( - new StringBuilder( ownerEntityTable ).append( "_" ) - .append( - associatedEntityTable != null ? - associatedEntityTable : - StringHelper.unqualify( propertyName ) - ).toString() - ); + String entityTableName = associatedEntityTable != null + ? associatedEntityTable + : StringHelper.unqualify(propertyName); + return tableName( ownerEntityTable + "_" + entityTableName ); } public String joinKeyColumnName(String joinedColumn, String joinedTable) { @@ -72,12 +68,10 @@ public String logicalCollectionTableName( return tableName; } else { - return new StringBuilder( ownerEntityTable ).append( "_" ) - .append( - associatedEntityTable != null ? - associatedEntityTable : - StringHelper.unqualify( propertyName ) - ).toString(); + String entityTableName = associatedEntityTable != null + ? associatedEntityTable + : StringHelper.unqualify(propertyName); + return ownerEntityTable + "_" + entityTableName; } } diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/PropertyInferredData.java b/hibernate-core/src/main/java/org/hibernate/cfg/PropertyInferredData.java index 57443b834962..89743c41aaac 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/PropertyInferredData.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/PropertyInferredData.java @@ -28,12 +28,7 @@ public class PropertyInferredData implements PropertyData { @Override public String toString() { - final StringBuilder sb = new StringBuilder(); - sb.append( "PropertyInferredData" ); - sb.append( "{property=" ).append( property ); - sb.append( ", declaringClass=" ).append( declaringClass ); - sb.append( '}' ); - return sb.toString(); + return String.format( "PropertyInferredData{property=%s, declaringClass=%s}", property, declaringClass ); } /**