From 99f8b0fd3de590880ae2a27ccc57f3b9f79c73d0 Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 9 Mar 2023 17:59:55 -0600 Subject: [PATCH] HHH-16260 - JdbcParameterRenderer not called with dynamic filters HHH-16256 - JdbcParameterRenderer to have an impact on write operations HHH-16273 - Support for Dialect native JdbcParameterRenderer --- .../src/test/resources/hibernate.properties | 3 - .../org/hibernate/cfg/AvailableSettings.java | 2 +- .../java/org/hibernate/dialect/Dialect.java | 1 - .../java/org/hibernate/dialect/H2Dialect.java | 15 +- .../hibernate/dialect/PostgreSQLDialect.java | 46 +-- .../dialect/PostgreSQLDriverKind.java | 1 + .../PessimisticReadSelectLockingStrategy.java | 6 +- .../PessimisticReadUpdateLockingStrategy.java | 8 +- ...PessimisticWriteSelectLockingStrategy.java | 6 +- ...PessimisticWriteUpdateLockingStrategy.java | 8 +- .../dialect/lock/SelectLockingStrategy.java | 6 +- .../dialect/lock/UpdateLockingStrategy.java | 8 +- .../id/insert/BasicSelectingDelegate.java | 2 +- .../id/insert/GetGeneratedKeysDelegate.java | 2 +- .../id/insert/IdentifierGeneratingInsert.java | 5 +- .../id/insert/InsertReturningDelegate.java | 2 +- .../id/insert/InsertSelectIdentityInsert.java | 9 +- .../id/insert/UniqueKeySelectingDelegate.java | 2 +- .../AbstractCollectionPersister.java | 15 +- .../entity/AbstractEntityPersister.java | 26 +- .../hibernate/sql/ComparisonRestriction.java | 48 +++ .../hibernate/sql/CompleteRestriction.java | 28 ++ .../main/java/org/hibernate/sql/Delete.java | 157 +++++----- .../main/java/org/hibernate/sql/Insert.java | 80 +++-- .../hibernate/sql/NullnessRestriction.java | 40 +++ .../java/org/hibernate/sql/Restriction.java | 22 ++ .../sql/RestrictionRenderingContext.java | 17 ++ .../java/org/hibernate/sql/SimpleSelect.java | 274 ++++++++--------- .../main/java/org/hibernate/sql/Update.java | 275 +++++++----------- .../JdbcParameterRendererStandard.java | 6 +- .../sql/ast/spi/AbstractSqlAstTranslator.java | 11 +- .../sql/ast/spi/JdbcParameterRenderer.java | 19 +- .../annotations/onetomany/OrderByTest.java | 2 +- .../collection/list/PersistentListTest.java | 6 +- .../sql/ast/JdbcParameterRendererTests.java | 4 +- .../internal/ValidityAuditStrategy.java | 20 +- 36 files changed, 637 insertions(+), 545 deletions(-) create mode 100644 hibernate-core/src/main/java/org/hibernate/sql/ComparisonRestriction.java create mode 100644 hibernate-core/src/main/java/org/hibernate/sql/CompleteRestriction.java create mode 100644 hibernate-core/src/main/java/org/hibernate/sql/NullnessRestriction.java create mode 100644 hibernate-core/src/main/java/org/hibernate/sql/Restriction.java create mode 100644 hibernate-core/src/main/java/org/hibernate/sql/RestrictionRenderingContext.java diff --git a/hibernate-agroal/src/test/resources/hibernate.properties b/hibernate-agroal/src/test/resources/hibernate.properties index dd62db2f27..2ce40bcd75 100644 --- a/hibernate-agroal/src/test/resources/hibernate.properties +++ b/hibernate-agroal/src/test/resources/hibernate.properties @@ -11,9 +11,6 @@ hibernate.connection.username @jdbc.user@ hibernate.connection.password @jdbc.pass@ hibernate.connection.init_sql @connection.init_sql@ -# some Agroal tests fail with native markers. not sure why yet -hibernate.dialect.native_param_markers=false - hibernate.jdbc.batch_size 10 hibernate.connection.provider_class AgroalConnectionProvider diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java index 0e2a7f9372..a75fff56ea 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AvailableSettings.java @@ -2789,7 +2789,7 @@ public interface AvailableSettings { String TIMEZONE_DEFAULT_STORAGE = "hibernate.timezone.default_storage"; /** - * Specifies whether to use JDBC parameter markers (`?`) or dialect native markers. + * Controls whether to use JDBC parameter markers (`?`) or dialect native markers. * * @implNote By default ({@code true}), dialect native markers are used, if any; disable * ({@code false}) to use the standard JDBC parameter markers (`?`) instead diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java index 441512b47e..99cbcd50bf 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/Dialect.java @@ -117,7 +117,6 @@ import org.hibernate.mapping.Index; import org.hibernate.mapping.Table; import org.hibernate.mapping.UserDefinedType; import org.hibernate.metamodel.mapping.EntityMappingType; -import org.hibernate.metamodel.mapping.internal.MappingModelCreationProcess; import org.hibernate.metamodel.spi.RuntimeModelCreationContext; import org.hibernate.persister.entity.Lockable; import org.hibernate.persister.entity.mutation.EntityMutationTarget; diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java index 2d8abf0928..eda131cad9 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java @@ -911,11 +911,18 @@ public class H2Dialect extends Dialect { @Override public JdbcParameterRenderer getNativeParameterRenderer() { - return H2Dialect::renderNatively; + return OrdinalParameterRenderer.INSTANCE; } - private static void renderNatively(int position, JdbcType jdbcType, SqlAppender appender, Dialect dialect) { - appender.append( "?" ); - appender.appendSql( position ); + public static class OrdinalParameterRenderer implements JdbcParameterRenderer { + /** + * Singleton access + */ + public static final OrdinalParameterRenderer INSTANCE = new OrdinalParameterRenderer(); + + @Override + public String renderJdbcParameter(int position, JdbcType jdbcType) { + return "?" + position; + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java index dd48ddd9f8..d62c9197f4 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDialect.java @@ -145,15 +145,28 @@ public class PostgreSQLDialect extends Dialect { protected final PostgreSQLDriverKind driverKind; private final OptionalTableUpdateStrategy optionalTableUpdateStrategy; + private final JdbcParameterRenderer parameterRenderer; public PostgreSQLDialect() { this( MINIMUM_VERSION ); } public PostgreSQLDialect(DialectResolutionInfo info) { - super(info); - driverKind = PostgreSQLDriverKind.determineKind( info ); - optionalTableUpdateStrategy = determineOptionalTableUpdateStrategy( info ); + this( info, PostgreSQLDriverKind.determineKind( info ) ); + } + + public PostgreSQLDialect(DatabaseVersion version) { + this( version, PostgreSQLDriverKind.PG_JDBC ); + } + + public PostgreSQLDialect(DatabaseVersion version, PostgreSQLDriverKind driverKind) { + super( version ); + + this.driverKind = driverKind; + this.optionalTableUpdateStrategy = determineOptionalTableUpdateStrategy( version ); + this.parameterRenderer = driverKind == PostgreSQLDriverKind.VERT_X + ? NativeParameterMarkers.INSTANCE + : super.getNativeParameterRenderer(); } private static OptionalTableUpdateStrategy determineOptionalTableUpdateStrategy(DatabaseVersion version) { @@ -162,18 +175,6 @@ public class PostgreSQLDialect extends Dialect { : PostgreSQLDialect::withoutMerge; } - public PostgreSQLDialect(DatabaseVersion version) { - super(version); - driverKind = PostgreSQLDriverKind.PG_JDBC; - optionalTableUpdateStrategy = determineOptionalTableUpdateStrategy( version ); - } - - public PostgreSQLDialect(DatabaseVersion version, PostgreSQLDriverKind driverKind) { - super(version); - this.driverKind = driverKind; - optionalTableUpdateStrategy = determineOptionalTableUpdateStrategy( version ); - } - @Override protected DatabaseVersion getMinimumSupportedVersion() { return MINIMUM_VERSION; @@ -1433,11 +1434,18 @@ public class PostgreSQLDialect extends Dialect { @Override public JdbcParameterRenderer getNativeParameterRenderer() { - return PostgreSQLDialect::renderNatively; + return parameterRenderer; } - private static void renderNatively(int position, JdbcType jdbcType, SqlAppender appender, Dialect dialect) { - appender.append( "$" ); - appender.appendSql( position ); + private static class NativeParameterMarkers implements JdbcParameterRenderer { + /** + * Singleton access + */ + public static final NativeParameterMarkers INSTANCE = new NativeParameterMarkers(); + + @Override + public String renderJdbcParameter(int position, JdbcType jdbcType) { + return "$" + position; + } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDriverKind.java b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDriverKind.java index a84b190706..26fbd4b49c 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDriverKind.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/PostgreSQLDriverKind.java @@ -14,6 +14,7 @@ import org.hibernate.engine.jdbc.dialect.spi.DialectResolutionInfo; */ public enum PostgreSQLDriverKind { PG_JDBC, + VERT_X, OTHER; public static PostgreSQLDriverKind determineKind(DialectResolutionInfo dialectResolutionInfo) { diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java index 4574b80cd2..16f41bf3f0 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadSelectLockingStrategy.java @@ -104,13 +104,13 @@ public class PessimisticReadSelectLockingStrategy extends AbstractSelectLockingS final SessionFactoryImplementor factory = getLockable().getFactory(); final LockOptions lockOptions = new LockOptions( getLockMode() ); lockOptions.setTimeOut( lockTimeout ); - final SimpleSelect select = new SimpleSelect( factory.getJdbcServices().getDialect() ) + final SimpleSelect select = new SimpleSelect( factory ) .setLockOptions( lockOptions ) .setTableName( getLockable().getRootTableName() ) .addColumn( getLockable().getRootTableIdentifierColumnNames()[0] ) - .addCondition( getLockable().getRootTableIdentifierColumnNames(), "=?" ); + .addRestriction( getLockable().getRootTableIdentifierColumnNames() ); if ( getLockable().isVersioned() ) { - select.addCondition( getLockable().getVersionColumnName(), "=?" ); + select.addRestriction( getLockable().getVersionColumnName() ); } if ( factory.getSessionFactoryOptions().isCommentsEnabled() ) { select.setComment( getLockMode() + " lock " + getLockable().getEntityName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java index 8741720f3a..0bf78de414 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticReadUpdateLockingStrategy.java @@ -122,11 +122,11 @@ public class PessimisticReadUpdateLockingStrategy implements LockingStrategy { protected String generateLockString() { final SessionFactoryImplementor factory = lockable.getFactory(); - final Update update = new Update( factory.getJdbcServices().getDialect() ); + final Update update = new Update( factory ); update.setTableName( lockable.getRootTableName() ); - update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() ); - update.setVersionColumnName( lockable.getVersionColumnName() ); - update.addColumn( lockable.getVersionColumnName() ); + update.addAssignment( lockable.getVersionColumnName() ); + update.addRestriction( lockable.getRootTableIdentifierColumnNames() ); + update.addRestriction( lockable.getVersionColumnName() ); if ( factory.getSessionFactoryOptions().isCommentsEnabled() ) { update.setComment( lockMode + " lock " + lockable.getEntityName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java index d845cb9e18..7399ad6444 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteSelectLockingStrategy.java @@ -107,13 +107,13 @@ public class PessimisticWriteSelectLockingStrategy extends AbstractSelectLocking final SessionFactoryImplementor factory = getLockable().getFactory(); final LockOptions lockOptions = new LockOptions( getLockMode() ); lockOptions.setTimeOut( lockTimeout ); - final SimpleSelect select = new SimpleSelect( factory.getJdbcServices().getDialect() ) + final SimpleSelect select = new SimpleSelect( factory ) .setLockOptions( lockOptions ) .setTableName( getLockable().getRootTableName() ) .addColumn( getLockable().getRootTableIdentifierColumnNames()[0] ) - .addCondition( getLockable().getRootTableIdentifierColumnNames(), "=?" ); + .addRestriction( getLockable().getRootTableIdentifierColumnNames() ); if ( getLockable().isVersioned() ) { - select.addCondition( getLockable().getVersionColumnName(), "=?" ); + select.addRestriction( getLockable().getVersionColumnName() ); } if ( factory.getSessionFactoryOptions().isCommentsEnabled() ) { select.setComment( getLockMode() + " lock " + getLockable().getEntityName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java index 66d2b01454..549a3dd692 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/PessimisticWriteUpdateLockingStrategy.java @@ -120,11 +120,11 @@ public class PessimisticWriteUpdateLockingStrategy implements LockingStrategy { protected String generateLockString() { final SessionFactoryImplementor factory = lockable.getFactory(); - final Update update = new Update( factory.getJdbcServices().getDialect() ); + final Update update = new Update( factory ); update.setTableName( lockable.getRootTableName() ); - update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() ); - update.setVersionColumnName( lockable.getVersionColumnName() ); - update.addColumn( lockable.getVersionColumnName() ); + update.addAssignment( lockable.getVersionColumnName() ); + update.addRestriction( lockable.getRootTableIdentifierColumnNames() ); + update.addRestriction( lockable.getVersionColumnName() ); if ( factory.getSessionFactoryOptions().isCommentsEnabled() ) { update.setComment( lockMode + " lock " + lockable.getEntityName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java index d9299b7a60..6c8b0ce879 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/SelectLockingStrategy.java @@ -102,13 +102,13 @@ public class SelectLockingStrategy extends AbstractSelectLockingStrategy { final SessionFactoryImplementor factory = getLockable().getFactory(); final LockOptions lockOptions = new LockOptions( getLockMode() ); lockOptions.setTimeOut( timeout ); - final SimpleSelect select = new SimpleSelect( factory.getJdbcServices().getDialect() ) + final SimpleSelect select = new SimpleSelect( factory ) .setLockOptions( lockOptions ) .setTableName( getLockable().getRootTableName() ) .addColumn( getLockable().getRootTableIdentifierColumnNames()[0] ) - .addCondition( getLockable().getRootTableIdentifierColumnNames(), "=?" ); + .addRestriction( getLockable().getRootTableIdentifierColumnNames() ); if ( getLockable().isVersioned() ) { - select.addCondition( getLockable().getVersionColumnName(), "=?" ); + select.addRestriction( getLockable().getVersionColumnName() ); } if ( factory.getSessionFactoryOptions().isCommentsEnabled() ) { select.setComment( getLockMode() + " lock " + getLockable().getEntityName() ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java b/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java index 809aa27984..a350411955 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/lock/UpdateLockingStrategy.java @@ -123,11 +123,11 @@ public class UpdateLockingStrategy implements LockingStrategy { protected String generateLockString() { final SessionFactoryImplementor factory = lockable.getFactory(); - final Update update = new Update( factory.getJdbcServices().getDialect() ); + final Update update = new Update( factory ); update.setTableName( lockable.getRootTableName() ); - update.addPrimaryKeyColumns( lockable.getRootTableIdentifierColumnNames() ); - update.setVersionColumnName( lockable.getVersionColumnName() ); - update.addColumn( lockable.getVersionColumnName() ); + update.addAssignment( lockable.getVersionColumnName() ); + update.addRestriction( lockable.getRootTableIdentifierColumnNames() ); + update.addRestriction( lockable.getVersionColumnName() ); if ( factory.getSessionFactoryOptions().isCommentsEnabled() ) { update.setComment( lockMode + " lock " + lockable.getEntityName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java index 6e17d22a7b..30829f46b3 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/BasicSelectingDelegate.java @@ -33,7 +33,7 @@ public class BasicSelectingDelegate extends AbstractSelectingDelegate { @Override @Deprecated public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert(SqlStringGenerationContext context) { - IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( dialect ); + IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( persister.getFactory() ); insert.addGeneratedColumns( persister.getRootTableKeyColumnNames(), (OnExecutionGenerator) persister.getGenerator() ); return insert; } diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/GetGeneratedKeysDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/GetGeneratedKeysDelegate.java index 114d779717..b711a1931f 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/GetGeneratedKeysDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/GetGeneratedKeysDelegate.java @@ -51,7 +51,7 @@ public class GetGeneratedKeysDelegate extends AbstractReturningDelegate { @Override @Deprecated public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert(SqlStringGenerationContext context) { - IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( dialect ); + IdentifierGeneratingInsert insert = new IdentifierGeneratingInsert( persister.getFactory() ); insert.addGeneratedColumns( persister.getRootTableKeyColumnNames(), (OnExecutionGenerator) persister.getGenerator() ); return insert; } diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java b/hibernate-core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java index 499597c1c5..435244d555 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/IdentifierGeneratingInsert.java @@ -6,6 +6,7 @@ */ package org.hibernate.id.insert; import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.sql.Insert; /** @@ -16,7 +17,7 @@ import org.hibernate.sql.Insert; * @author Steve Ebersole */ public class IdentifierGeneratingInsert extends Insert { - public IdentifierGeneratingInsert(Dialect dialect) { - super( dialect ); + public IdentifierGeneratingInsert(SessionFactoryImplementor sessionFactory) { + super( sessionFactory ); } } diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/InsertReturningDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/InsertReturningDelegate.java index e3b7f29f7f..f228ff7f53 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/InsertReturningDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/InsertReturningDelegate.java @@ -45,7 +45,7 @@ public class InsertReturningDelegate extends AbstractReturningDelegate { @Override @Deprecated public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert(SqlStringGenerationContext context) { - InsertSelectIdentityInsert insert = new InsertSelectIdentityInsert( dialect ); + InsertSelectIdentityInsert insert = new InsertSelectIdentityInsert( persister.getFactory() ); insert.addGeneratedColumns( persister.getRootTableKeyColumnNames(), (OnExecutionGenerator) persister.getGenerator() ); return insert; } diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java b/hibernate-core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java index df34a0d730..4623a5b27a 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/InsertSelectIdentityInsert.java @@ -7,6 +7,7 @@ package org.hibernate.id.insert; import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.sql.Insert; import org.hibernate.generator.OnExecutionGenerator; @@ -20,6 +21,10 @@ import org.hibernate.generator.OnExecutionGenerator; public class InsertSelectIdentityInsert extends IdentifierGeneratingInsert { protected String identityColumnName; + public InsertSelectIdentityInsert(SessionFactoryImplementor sessionFactory) { + super( sessionFactory ); + } + public Insert addIdentityColumn(String columnName) { identityColumnName = columnName; return super.addIdentityColumn( columnName ); @@ -36,10 +41,6 @@ public class InsertSelectIdentityInsert extends IdentifierGeneratingInsert { return super.addGeneratedColumns( columnNames, generator ); } - public InsertSelectIdentityInsert(Dialect dialect) { - super( dialect ); - } - public String toStatementString() { return getDialect().getIdentityColumnSupport() .appendIdentitySelectToInsert( identityColumnName, super.toStatementString() ); diff --git a/hibernate-core/src/main/java/org/hibernate/id/insert/UniqueKeySelectingDelegate.java b/hibernate-core/src/main/java/org/hibernate/id/insert/UniqueKeySelectingDelegate.java index 6c47e9b03f..332af3000f 100644 --- a/hibernate-core/src/main/java/org/hibernate/id/insert/UniqueKeySelectingDelegate.java +++ b/hibernate-core/src/main/java/org/hibernate/id/insert/UniqueKeySelectingDelegate.java @@ -54,7 +54,7 @@ public class UniqueKeySelectingDelegate extends AbstractSelectingDelegate { @Override @Deprecated public IdentifierGeneratingInsert prepareIdentifierGeneratingInsert(SqlStringGenerationContext context) { - return new IdentifierGeneratingInsert( dialect ); + return new IdentifierGeneratingInsert( persister.getFactory() ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java index c6aa22b351..afea4e6e47 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/collection/AbstractCollectionPersister.java @@ -128,7 +128,6 @@ import org.hibernate.sql.model.jdbc.JdbcMutationOperation; import org.hibernate.sql.results.graph.DomainResult; import org.hibernate.sql.results.graph.internal.ImmutableFetchList; import org.hibernate.sql.results.internal.SqlSelectionImpl; -import org.hibernate.type.AssociationType; import org.hibernate.type.CollectionType; import org.hibernate.type.CompositeType; import org.hibernate.type.EntityType; @@ -1023,7 +1022,7 @@ public abstract class AbstractCollectionPersister "count(" + getElementColumnNames()[0] + ")"; // sets, maps, bags return new SimpleSelect( getFactory() ) .setTableName( getTableName() ) - .addCondition( getKeyColumnNames(), "=?" ) + .addRestriction( getKeyColumnNames() ) .addWhereToken( sqlWhereString ) .addColumn( selectValue ) .toStatementString(); @@ -1035,9 +1034,9 @@ public abstract class AbstractCollectionPersister } return new SimpleSelect( getFactory() ) .setTableName( getTableName() ) - .addCondition( getKeyColumnNames(), "=?" ) - .addCondition( getIndexColumnNames(), "=?" ) - .addCondition( indexFormulas, "=?" ) + .addRestriction( getKeyColumnNames() ) + .addRestriction( getIndexColumnNames() ) + .addRestriction( indexFormulas ) .addWhereToken( sqlWhereString ) .addColumn( "1" ) .toStatementString(); @@ -1047,9 +1046,9 @@ public abstract class AbstractCollectionPersister protected String generateDetectRowByElementString() { return new SimpleSelect( getFactory() ) .setTableName( getTableName() ) - .addCondition( getKeyColumnNames(), "=?" ) - .addCondition( getElementColumnNames(), "=?" ) - .addCondition( elementFormulas, "=?" ) + .addRestriction( getKeyColumnNames() ) + .addRestriction( getElementColumnNames() ) + .addRestriction( elementFormulas ) .addWhereToken( sqlWhereString ) .addColumn( "1" ) .toStatementString(); diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index 4c877a926d..584a6c38ad 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -1880,8 +1880,7 @@ public abstract class AbstractEntityPersister * Generate the SQL that selects the version number by id */ public String generateSelectVersionString() { - final SimpleSelect select = new SimpleSelect( getFactory().getJdbcServices().getDialect() ) - .setTableName( getVersionedTableName() ); + final SimpleSelect select = new SimpleSelect( getFactory() ).setTableName( getVersionedTableName() ); if ( isVersioned() ) { select.addColumn( getVersionColumnName(), VERSION_COLUMN_ALIAS ); } @@ -1891,7 +1890,7 @@ public abstract class AbstractEntityPersister if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) { select.setComment( "get version " + getEntityName() ); } - return select.addCondition( rootTableKeyColumnNames, "=?" ).toStatementString(); + return select.addRestriction( rootTableKeyColumnNames ).toStatementString(); } private GeneratedValuesProcessor createGeneratedValuesProcessor(EventType timing) { @@ -2711,12 +2710,11 @@ public abstract class AbstractEntityPersister @Override public String getSelectByUniqueKeyString(String[] propertyNames) { - final SimpleSelect select = - new SimpleSelect( getFactory().getJdbcServices().getDialect() ) - .setTableName( getTableName(0) ) - .addColumns( getKeyColumns(0) ); + final SimpleSelect select = new SimpleSelect( getFactory() ) + .setTableName( getTableName(0) ) + .addColumns( getKeyColumns(0) ); for ( int i = 0; i < propertyNames.length; i++ ) { - select.addCondition( getPropertyColumnNames( propertyNames[i] ), "= ?" ); + select.addRestriction( getPropertyColumnNames( propertyNames[i] ) ); } return select.toStatementString(); } @@ -6010,9 +6008,9 @@ public abstract class AbstractEntityPersister @Deprecated(forRemoval = true) @Remove public String generateDeleteString(int j) { - final Delete delete = new Delete() + final Delete delete = new Delete( getFactory() ) .setTableName( getTableName( j ) ) - .addPrimaryKeyColumns( getKeyColumns( j ) ); + .addColumnRestriction( getKeyColumns( j ) ); if ( j == 0 ) { delete.setVersionColumnName( getVersionColumnName() ); } @@ -6108,9 +6106,9 @@ public abstract class AbstractEntityPersister int span = getTableSpan(); String[] deleteStrings = new String[span]; for ( int j = span - 1; j >= 0; j-- ) { - final Delete delete = new Delete() + final Delete delete = new Delete( getFactory() ) .setTableName( getTableName( j ) ) - .addPrimaryKeyColumns( getKeyColumns( j ) ); + .addColumnRestriction( getKeyColumns( j ) ); if ( getFactory().getSessionFactoryOptions().isCommentsEnabled() ) { delete.setComment( "delete " + getEntityName() + " [" + j + "]" ); } @@ -6125,10 +6123,10 @@ public abstract class AbstractEntityPersister boolean[] propertyNullness = types[i].toColumnNullness( loadedState[i], getFactory() ); for ( int k = 0; k < propertyNullness.length; k++ ) { if ( propertyNullness[k] ) { - delete.addWhereFragment( propertyColumnNames[k] + " = ?" ); + delete.addColumnRestriction( propertyColumnNames[k] ); } else { - delete.addWhereFragment( propertyColumnNames[k] + " is null" ); + delete.addColumnNullnessRestriction( propertyColumnNames[k] ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ComparisonRestriction.java b/hibernate-core/src/main/java/org/hibernate/sql/ComparisonRestriction.java new file mode 100644 index 0000000000..15cb6dc828 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/ComparisonRestriction.java @@ -0,0 +1,48 @@ +/* + * 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 http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.sql; + +import org.hibernate.Internal; + +/** + * A binary-comparison restriction + * + * @author Steve Ebersole + */ +@Internal +public class ComparisonRestriction implements Restriction { + private final String lhs; + private final String operator; + private final String rhs; + + public ComparisonRestriction(String lhs) { + this( lhs, "?" ); + } + + public ComparisonRestriction(String lhs, String rhs) { + this( lhs, "=", rhs ); + } + + public ComparisonRestriction(String lhs, String operator, String rhs) { + this.lhs = lhs; + this.operator = operator; + this.rhs = rhs; + } + + @Override + public void render(StringBuilder sqlBuffer, RestrictionRenderingContext context) { + sqlBuffer.append( lhs ); + sqlBuffer.append( operator ); + + if ( "?".equals( rhs ) ) { + sqlBuffer.append( context.makeParameterMarker() ); + } + else { + sqlBuffer.append( rhs ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/CompleteRestriction.java b/hibernate-core/src/main/java/org/hibernate/sql/CompleteRestriction.java new file mode 100644 index 0000000000..73e1324bbb --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/CompleteRestriction.java @@ -0,0 +1,28 @@ +/* + * 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 http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.sql; + +import org.hibernate.Internal; + +/** + * For a complete predicate. E.g. {@link org.hibernate.annotations.Where} + * + * @author Steve Ebersole + */ +@Internal +public class CompleteRestriction implements Restriction { + private final String predicate; + + public CompleteRestriction(String predicate) { + this.predicate = predicate; + } + + @Override + public void render(StringBuilder sqlBuffer, RestrictionRenderingContext context) { + sqlBuffer.append( predicate ); + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Delete.java b/hibernate-core/src/main/java/org/hibernate/sql/Delete.java index d57c1ec24d..c67ceb846e 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Delete.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Delete.java @@ -5,12 +5,16 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.sql; +import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import org.hibernate.Internal; import org.hibernate.dialect.Dialect; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.sql.ast.spi.JdbcParameterRenderer; /** * A SQL {@code DELETE} statement. @@ -21,15 +25,21 @@ import org.hibernate.dialect.Dialect; public class Delete { protected String tableName; - protected String versionColumnName; - protected String where; protected String comment; - protected Map primaryKeyColumns = new LinkedHashMap<>(); + protected final List whereFragments = new ArrayList<>(); - public Delete setComment(String comment) { - this.comment = comment; - return this; + private final JdbcParameterRenderer jdbcParameterRenderer; + private final boolean standardParamRendering; + private int parameterCount; + + public Delete(SessionFactoryImplementor factory) { + this( factory.getServiceRegistry().getService( JdbcParameterRenderer.class ) ); + } + + public Delete(JdbcParameterRenderer jdbcParameterRenderer) { + this.jdbcParameterRenderer = jdbcParameterRenderer; + this.standardParamRendering = JdbcParameterRenderer.isStandardRenderer( jdbcParameterRenderer ); } public Delete setTableName(String tableName) { @@ -37,93 +47,80 @@ public class Delete { return this; } - public String toStatementString() { - StringBuilder buf = new StringBuilder( tableName.length() + 10 ); - if ( comment!=null ) { - buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); - } - buf.append( "delete from " ).append(tableName); - if ( where != null || !primaryKeyColumns.isEmpty() || versionColumnName != null ) { - buf.append( " where " ); - } - boolean conditionsAppended = false; - Iterator> iter = primaryKeyColumns.entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry e = iter.next(); - buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); - if ( iter.hasNext() ) { - buf.append( " and " ); + public Delete setComment(String comment) { + this.comment = comment; + return this; + } + + @SuppressWarnings("UnusedReturnValue") + public Delete addColumnRestriction(String columnName) { + final String paramMarker = jdbcParameterRenderer.renderJdbcParameter( ++parameterCount, null ); + this.whereFragments.add( columnName + "=" + paramMarker ); + return this; + } + + @SuppressWarnings("UnusedReturnValue") + public Delete addColumnRestriction(String... columnNames) { + for ( int i = 0; i < columnNames.length; i++ ) { + if ( columnNames[i] == null ) { + continue; } - conditionsAppended = true; - } - if ( where!=null ) { - if ( conditionsAppended ) { - buf.append( " and " ); - } - buf.append( where ); - conditionsAppended = true; - } - if ( versionColumnName!=null ) { - if ( conditionsAppended ) { - buf.append( " and " ); - } - buf.append( versionColumnName ).append( "=?" ); - } - return buf.toString(); - } - - public Delete setWhere(String where) { - this.where=where; - return this; - } - - public Delete addWhereFragment(String fragment) { - if ( where == null ) { - where = fragment; - } - else { - where += ( " and " + fragment ); + addColumnRestriction( columnNames[i] ); } return this; } - public Delete setPrimaryKeyColumnNames(String[] columnNames) { - this.primaryKeyColumns.clear(); - addPrimaryKeyColumns(columnNames); - return this; - } - - public Delete addPrimaryKeyColumns(String[] columnNames) { - for ( String columnName : columnNames ) { - addPrimaryKeyColumn( columnName, "?" ); - } + @SuppressWarnings("UnusedReturnValue") + public Delete addColumnNullnessRestriction(String columnName) { + addColumnNullnessRestriction( columnName, false ); return this; } - - public Delete addPrimaryKeyColumns(String[] columnNames, boolean[] includeColumns, String[] valueExpressions) { - for ( int i=0; i 0 ) { + buf.append( " and " ); + } + buf.append( whereFragments.get(i) ); + } + } + + private void applyComment(StringBuilder buf) { + if ( comment != null ) { + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); + } + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Insert.java b/hibernate-core/src/main/java/org/hibernate/sql/Insert.java index b70291ce7d..5a75f8d453 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Insert.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Insert.java @@ -5,7 +5,7 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.sql; -import java.util.HashMap; + import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; @@ -14,7 +14,11 @@ import org.hibernate.Internal; import org.hibernate.MappingException; import org.hibernate.dialect.Dialect; import org.hibernate.dialect.identity.IdentityColumnSupport; +import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.generator.OnExecutionGenerator; +import org.hibernate.sql.ast.spi.JdbcParameterRenderer; + +import static org.hibernate.sql.ast.spi.JdbcParameterRenderer.isStandardRenderer; /** * A SQL {@code INSERT} statement. @@ -23,16 +27,28 @@ import org.hibernate.generator.OnExecutionGenerator; */ @Internal public class Insert { - private final Dialect dialect; protected String tableName; protected String comment; protected Map columns = new LinkedHashMap<>(); - protected Map lobColumns; - public Insert(Dialect dialect) { + private final Dialect dialect; + private final JdbcParameterRenderer jdbcParameterRenderer; + private final boolean standardParamRendering; + private int parameterCount; + + public Insert(SessionFactoryImplementor sessionFactory) { + this( + sessionFactory.getJdbcServices().getDialect(), + sessionFactory.getServiceRegistry().getService( JdbcParameterRenderer.class ) + ); + } + + public Insert(Dialect dialect, JdbcParameterRenderer jdbcParameterRenderer) { this.dialect = dialect; + this.jdbcParameterRenderer = jdbcParameterRenderer; + this.standardParamRendering = isStandardRenderer( jdbcParameterRenderer ); } protected Dialect getDialect() { @@ -82,14 +98,6 @@ public class Insert { return this; } - public void addLobColumn(String columnName, String valueExpression) { - assert dialect.forceLobAsLastValue(); - if ( lobColumns == null ) { - lobColumns = new HashMap<>(); - } - lobColumns.put( columnName, valueExpression ); - } - public Insert addIdentityColumn(String columnName) { final IdentityColumnSupport identityColumnSupport = dialect.getIdentityColumnSupport(); if ( identityColumnSupport.hasIdentityInsertKeyword() ) { @@ -117,14 +125,15 @@ public class Insert { } public String toStatementString() { - StringBuilder buf = new StringBuilder( columns.size()*15 + tableName.length() + 10 ); + final StringBuilder buf = new StringBuilder( columns.size()*15 + tableName.length() + 10 ); + if ( comment != null ) { buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); } - buf.append("insert into ").append(tableName); + buf.append( "insert into " ).append( tableName ); - if ( columns.size()==0 && lobColumns == null ) { + if ( columns.isEmpty() ) { if ( dialect.supportsNoColumnsInsert() ) { buf.append( ' ' ).append( dialect.getNoColumnsInsertString() ); } @@ -140,51 +149,38 @@ public class Insert { } else { buf.append( " (" ); - renderColumnsClause( buf ); + renderInsertionSpec( buf ); buf.append( ") values (" ); - renderValuesClause( buf ); - buf.append(')'); + renderRowValues( buf ); + buf.append( ')' ); } return buf.toString(); } - private void renderColumnsClause(StringBuilder buf) { + + private void renderInsertionSpec(StringBuilder buf) { final Iterator itr = columns.keySet().iterator(); while ( itr.hasNext() ) { buf.append( itr.next() ); - if ( itr.hasNext() || lobColumns != null ) { + if ( itr.hasNext() ) { buf.append( ", " ); } } - - if ( lobColumns != null ) { - final Iterator columnsAtEndItr = lobColumns.keySet().iterator(); - while ( columnsAtEndItr.hasNext() ) { - buf.append( columnsAtEndItr.next() ); - if ( columnsAtEndItr.hasNext() ) { - buf.append( ", " ); - } - } - } } - private void renderValuesClause(StringBuilder buf) { + private void renderRowValues(StringBuilder buf) { final Iterator itr = columns.values().iterator(); while ( itr.hasNext() ) { - buf.append( itr.next() ); - if ( itr.hasNext() || lobColumns != null ) { + buf.append( normalizeExpressionFragment( itr.next() ) ); + if ( itr.hasNext() ) { buf.append( ", " ); } } + } - if ( lobColumns != null ) { - final Iterator columnsAtEndItr = lobColumns.values().iterator(); - while ( columnsAtEndItr.hasNext() ) { - buf.append( columnsAtEndItr.next() ); - if ( columnsAtEndItr.hasNext() ) { - buf.append( ", " ); - } - } - } + private String normalizeExpressionFragment(String rhs) { + return rhs.equals( "?" ) && !standardParamRendering + ? jdbcParameterRenderer.renderJdbcParameter( ++parameterCount, null ) + : rhs; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/NullnessRestriction.java b/hibernate-core/src/main/java/org/hibernate/sql/NullnessRestriction.java new file mode 100644 index 0000000000..b607e59630 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/NullnessRestriction.java @@ -0,0 +1,40 @@ +/* + * 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 http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.sql; + +import org.hibernate.Internal; + +/** + * Nullness restriction - is [not] null + * + * @author Steve Ebersole + */ +@Internal +public class NullnessRestriction implements Restriction { + private final String columnName; + private final boolean negated; + + public NullnessRestriction(String columnName) { + this( columnName, false ); + } + + public NullnessRestriction(String columnName, boolean negated) { + this.columnName = columnName; + this.negated = negated; + } + + @Override + public void render(StringBuilder sqlBuffer, RestrictionRenderingContext context) { + sqlBuffer.append( columnName ); + if ( negated ) { + sqlBuffer.append( " is not null" ); + } + else { + sqlBuffer.append( " is null" ); + } + } +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Restriction.java b/hibernate-core/src/main/java/org/hibernate/sql/Restriction.java new file mode 100644 index 0000000000..6c1a1d4735 --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/Restriction.java @@ -0,0 +1,22 @@ +/* + * 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 http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.sql; + +import org.hibernate.Internal; + +/** + * A restriction (predicate) to be applied to a query + * + * @author Steve Ebersole + */ +@Internal +public interface Restriction { + /** + * Render the restriction into the SQL buffer + */ + void render(StringBuilder sqlBuffer, RestrictionRenderingContext context); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/RestrictionRenderingContext.java b/hibernate-core/src/main/java/org/hibernate/sql/RestrictionRenderingContext.java new file mode 100644 index 0000000000..049314185f --- /dev/null +++ b/hibernate-core/src/main/java/org/hibernate/sql/RestrictionRenderingContext.java @@ -0,0 +1,17 @@ +/* + * 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 http://www.gnu.org/licenses/lgpl-2.1.html. + */ +package org.hibernate.sql; + +import org.hibernate.Internal; + +/** + * @author Steve Ebersole + */ +@Internal +public interface RestrictionRenderingContext { + String makeParameterMarker(); +} diff --git a/hibernate-core/src/main/java/org/hibernate/sql/SimpleSelect.java b/hibernate-core/src/main/java/org/hibernate/sql/SimpleSelect.java index 5047a82e9f..e580cd3eee 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/SimpleSelect.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/SimpleSelect.java @@ -9,7 +9,6 @@ package org.hibernate.sql; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; @@ -27,47 +26,44 @@ import org.hibernate.sql.ast.spi.JdbcParameterRenderer; * @author Gavin King */ @Internal -public class SimpleSelect { +public class SimpleSelect implements RestrictionRenderingContext { protected String tableName; protected String orderBy; protected String comment; protected List columns = new ArrayList<>(); protected Map aliases = new HashMap<>(); - protected List whereTokens = new ArrayList<>(); + protected List restrictions = new ArrayList<>(); protected LockOptions lockOptions = new LockOptions( LockMode.READ ); private final SessionFactoryImplementor factory; private final Dialect dialect; - private JdbcParameterRenderer _jdbcParameterRenderer; + private final JdbcParameterRenderer jdbcParameterRenderer; + private int parameterCount; public SimpleSelect(SessionFactoryImplementor factory) { this.factory = factory; this.dialect = factory.getJdbcServices().getDialect(); + this.jdbcParameterRenderer = factory.getServiceRegistry().getService( JdbcParameterRenderer.class ); } - //private static final Alias DEFAULT_ALIAS = new Alias(10, null); + @Override + public String makeParameterMarker() { + return jdbcParameterRenderer.renderJdbcParameter( ++parameterCount, null ); + } - - public SimpleSelect addColumns(String[] columnNames, String[] columnAliases) { - for ( int i = 0; i < columnNames.length; i++ ) { - if ( columnNames[i] != null ) { - addColumn( columnNames[i], columnAliases[i] ); - } - } - return this; - } - - public SimpleSelect addColumns(String[] columns, String[] aliases, boolean[] ignore) { - for ( int i = 0; i < ignore.length; i++ ) { - if ( !ignore[i] && columns[i] != null ) { - addColumn( columns[i], aliases[i] ); - } - } + /** + * Sets the name of the table we are selecting from + */ + public SimpleSelect setTableName(String tableName) { + this.tableName = tableName; return this; } + /** + * Adds selections + */ public SimpleSelect addColumns(String[] columnNames) { for ( String columnName : columnNames ) { if ( columnName != null ) { @@ -77,20 +73,66 @@ public class SimpleSelect { return this; } + /** + * Adds a selection + */ public SimpleSelect addColumn(String columnName) { columns.add( columnName ); - //aliases.put( columnName, DEFAULT_ALIAS.toAliasString(columnName) ); return this; } + /** + * Adds a selection, with an alias + */ public SimpleSelect addColumn(String columnName, String alias) { columns.add( columnName ); aliases.put( columnName, alias ); return this; } - public SimpleSelect setTableName(String tableName) { - this.tableName = tableName; + /** + * Appends a complete {@linkplain org.hibernate.annotations.Where where} condition. + * The {@code condition} is added as-is. + */ + public SimpleSelect addWhereToken(String condition) { + if ( condition != null ) { + restrictions.add( new CompleteRestriction( condition ) ); + } + return this; + } + + /** + * Appends a restriction comparing the {@code columnName} for equality with a parameter + * + * @see #addRestriction(String, String, String) + */ + public SimpleSelect addRestriction(String columnName) { + restrictions.add( new ComparisonRestriction( columnName ) ); + return this; + } + + /** + * Appends a restriction based on the comparison between {@code lhs} and {@code rhs}. + *

+ * The {@code rhs} is checked for parameter marker and processed via {@link JdbcParameterRenderer} + * if needed. + */ + public SimpleSelect addRestriction(String lhs, String op, String rhs) { + restrictions.add( new ComparisonRestriction( lhs, op, rhs ) ); + return this; + } + + /** + * Appends a restriction comparing each name in {@code columnNames} for equality with a parameter + * + * @see #addRestriction(String) + */ + public SimpleSelect addRestriction(String... columnNames) { + for ( int i = 0; i < columnNames.length; i++ ) { + if ( columnNames[i] != null ) { + addRestriction( columnNames[i] ); + } + } return this; } @@ -104,114 +146,6 @@ public class SimpleSelect { return this; } - /** - * Appends a complete {@linkplain org.hibernate.annotations.Where where} fragment. The {@code token} is added as-is - */ - public SimpleSelect addWhereToken(String token) { - if (token != null ) { - and(); - whereTokens.add( token ); - } - return this; - } - - private void and() { - if ( !whereTokens.isEmpty() ) { - whereTokens.add( "and" ); - } - } - - private JdbcParameterRenderer jdbcParameterRenderer() { - if ( _jdbcParameterRenderer == null ) { - _jdbcParameterRenderer = factory.getServiceRegistry().getService( JdbcParameterRenderer.class ); - } - return _jdbcParameterRenderer; - } - - public SimpleSelect addCondition(String lhs, String op, String rhs) { - and(); - whereTokens.add( lhs + ' ' + op + ' ' + rhs ); - return this; - } - - public SimpleSelect addCondition(String lhs, String condition) { - and(); - whereTokens.add( lhs + ' ' + condition ); - return this; - } - - public SimpleSelect addCondition(String[] lhs, String condition) { - for ( String lh : lhs ) { - if ( lh != null ) { - addCondition( lh, condition ); - } - } - return this; - } - - public String toStatementString() { - StringBuilder buf = new StringBuilder( - columns.size() * 10 + - tableName.length() + - whereTokens.size() * 10 + - 10 - ); - - if ( comment != null ) { - buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); - } - - buf.append( "select " ); - Set uniqueColumns = new HashSet<>(); - Iterator iter = columns.iterator(); - boolean appendComma = false; - while ( iter.hasNext() ) { - String col = iter.next(); - String alias = aliases.get( col ); - if ( uniqueColumns.add( alias == null ? col : alias ) ) { - if ( appendComma ) { - buf.append( ", " ); - } - buf.append( col ); - if ( alias != null && !alias.equals( col ) ) { - buf.append( " as " ) - .append( alias ); - } - appendComma = true; - } - } - - buf.append( " from " ) - .append( dialect.appendLockHint( lockOptions, tableName ) ); - - if ( whereTokens.size() > 0 ) { - buf.append( " where " ) - .append( toWhereClause() ); - } - - if ( orderBy != null ) { - buf.append( orderBy ); - } - - if ( lockOptions != null ) { - buf = new StringBuilder( dialect.applyLocksToSql( buf.toString(), lockOptions, null ) ); - } - - return dialect.transformSelectString( buf.toString() ); - } - - public String toWhereClause() { - StringBuilder buf = new StringBuilder( whereTokens.size() * 5 ); - Iterator iter = whereTokens.iterator(); - while ( iter.hasNext() ) { - buf.append( iter.next() ); - if ( iter.hasNext() ) { - buf.append( ' ' ); - } - } - return buf.toString(); - } - public SimpleSelect setOrderBy(String orderBy) { this.orderBy = orderBy; return this; @@ -222,4 +156,80 @@ public class SimpleSelect { return this; } + public String toStatementString() { + final StringBuilder buf = new StringBuilder( + columns.size() * 10 + + tableName.length() + + restrictions.size() * 10 + + 10 + ); + + applyComment( buf ); + applySelectClause( buf ); + applyFromClause( buf ); + applyWhereClause( buf ); + applyOrderBy( buf ); + + final String selectString = (lockOptions != null) + ? dialect.applyLocksToSql( buf.toString(), lockOptions, null ) + : buf.toString(); + + return dialect.transformSelectString( selectString ); + } + + private void applyComment(StringBuilder buf) { + if ( comment != null ) { + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); + } + } + + private void applySelectClause(StringBuilder buf) { + buf.append( "select " ); + + boolean appendComma = false; + final Set uniqueColumns = new HashSet<>(); + for ( int i = 0; i < columns.size(); i++ ) { + final String col = columns.get( i ); + final String alias = aliases.get( col ); + + if ( uniqueColumns.add( alias == null ? col : alias ) ) { + if ( appendComma ) { + buf.append( ", " ); + } + buf.append( col ); + if ( alias != null && !alias.equals( col ) ) { + buf.append( " as " ).append( alias ); + } + appendComma = true; + } + } + } + + private void applyFromClause(StringBuilder buf) { + buf.append( " from " ).append( dialect.appendLockHint( lockOptions, tableName ) ); + } + + private void applyWhereClause(StringBuilder buf) { + if ( restrictions.isEmpty() ) { + return; + } + + buf.append( " where " ); + + for ( int i = 0; i < restrictions.size(); i++ ) { + if ( i > 0 ) { + buf.append( " and " ); + } + + final Restriction restriction = restrictions.get( i ); + restriction.render( buf, this ); + } + } + + private void applyOrderBy(StringBuilder buf) { + if ( orderBy != null ) { + buf.append( ' ' ).append( orderBy ); + } + } + } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/Update.java b/hibernate-core/src/main/java/org/hibernate/sql/Update.java index d0ba097630..30a6584843 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/Update.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/Update.java @@ -5,14 +5,16 @@ * See the lgpl.txt file in the root directory or . */ package org.hibernate.sql; -import java.util.HashMap; +import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import org.hibernate.Internal; import org.hibernate.dialect.Dialect; -import org.hibernate.metamodel.mapping.ModelPart; +import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.sql.ast.spi.JdbcParameterRenderer; /** * A SQL {@code UPDATE} statement. @@ -20,223 +22,142 @@ import org.hibernate.metamodel.mapping.ModelPart; * @author Gavin King */ @Internal -public class Update { - +public class Update implements RestrictionRenderingContext { protected String tableName; - protected String versionColumnName; - protected String where; - protected String assignments; protected String comment; + protected Map assignments = new LinkedHashMap<>(); + protected List restrictions = new ArrayList<>(); - protected Map primaryKeyColumns = new LinkedHashMap<>(); - protected Map columns = new LinkedHashMap<>(); - protected Map lobColumns; - protected Map whereColumns = new LinkedHashMap<>(); - - private Dialect dialect; - - public Update(Dialect dialect) { - this.dialect = dialect; + private final JdbcParameterRenderer jdbcParameterRenderer; + private final boolean standardParamRendering; + private int parameterCount; + + public Update(SessionFactoryImplementor factory) { + this( factory.getServiceRegistry().getService( JdbcParameterRenderer.class ) ); + } + + public Update(JdbcParameterRenderer jdbcParameterRenderer) { + this.jdbcParameterRenderer = jdbcParameterRenderer; + this.standardParamRendering = JdbcParameterRenderer.isStandardRenderer( jdbcParameterRenderer ); } public String getTableName() { return tableName; } - public Update appendAssignmentFragment(String fragment) { - if ( assignments == null ) { - assignments = fragment; - } - else { - assignments += ", " + fragment; - } - return this; - } - public Update setTableName(String tableName) { this.tableName = tableName; return this; } - public Update setPrimaryKeyColumnNames(String[] columnNames) { - this.primaryKeyColumns.clear(); - addPrimaryKeyColumns(columnNames); - return this; - } - - public Update addPrimaryKeyColumns(String[] columnNames) { - for ( String columnName : columnNames ) { - addPrimaryKeyColumn( columnName, "?" ); - } - return this; - } - - public Update addPrimaryKeyColumns(ModelPart keyPart) { - keyPart.forEachSelectable( (selectionIndex, selectableMapping) -> { - addPrimaryKeyColumn( selectableMapping.getSelectionExpression(), "?" ); - } ); - return this; - } - - public Update addPrimaryKeyColumns(String[] columnNames, boolean[] includeColumns, String[] valueExpressions) { - for ( int i=0; i(); - } - lobColumns.put( columnName, valueExpression ); + private String normalizeExpressionFragment(String rhs) { + return rhs.equals( "?" ) && !standardParamRendering + ? jdbcParameterRenderer.renderJdbcParameter( ++parameterCount, null ) + : rhs; } - public Update addWhereColumns(String[] columnNames) { - for ( String columnName : columnNames ) { - addWhereColumn( columnName ); - } - return this; - } - - public Update addWhereColumns(String[] columnNames, String valueExpression) { - for ( String columnName : columnNames ) { - addWhereColumn( columnName, valueExpression ); - } - return this; - } - - public Update addWhereColumn(String columnName) { - return addWhereColumn(columnName, "=?"); - } - - public Update addWhereColumn(String columnName, String valueExpression) { - whereColumns.put(columnName, valueExpression); - return this; - } - - public Update setWhere(String where) { - this.where=where; + public Update addNullnessRestriction(String column) { + restrictions.add( new NullnessRestriction( column ) ); return this; } public String toStatementString() { - StringBuilder buf = new StringBuilder( (columns.size() * 15) + tableName.length() + 10 ); - if ( comment!=null ) { - buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); - } - buf.append( "update " ).append( tableName ).append( " set " ); - boolean assignmentsAppended = false; - Iterator> iter = columns.entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry e = iter.next(); - buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); - if ( iter.hasNext() ) { - buf.append( ", " ); - } - assignmentsAppended = true; - } - if ( assignments != null ) { - if ( assignmentsAppended ) { - buf.append( ", " ); - } - buf.append( assignments ); - } + final StringBuilder buf = new StringBuilder( ( assignments.size() * 15) + tableName.length() + 10 ); - boolean conditionsAppended = false; - if ( !primaryKeyColumns.isEmpty() || where != null || !whereColumns.isEmpty() || versionColumnName != null ) { - buf.append( " where " ); - } - iter = primaryKeyColumns.entrySet().iterator(); - while ( iter.hasNext() ) { - Map.Entry e = iter.next(); - buf.append( e.getKey() ).append( '=' ).append( e.getValue() ); - if ( iter.hasNext() ) { - buf.append( " and " ); - } - conditionsAppended = true; - } - if ( where != null ) { - if ( conditionsAppended ) { - buf.append( " and " ); - } - buf.append( where ); - conditionsAppended = true; - } - iter = whereColumns.entrySet().iterator(); - while ( iter.hasNext() ) { - final Map.Entry e = iter.next(); - if ( conditionsAppended ) { - buf.append( " and " ); - } - buf.append( e.getKey() ).append( e.getValue() ); - conditionsAppended = true; - } - if ( versionColumnName != null ) { - if ( conditionsAppended ) { - buf.append( " and " ); - } - buf.append( versionColumnName ).append( "=?" ); - } + applyComment( buf ); + buf.append( "update " ).append( tableName ); + applyAssignments( buf ); + applyRestrictions( buf ); return buf.toString(); } + + private void applyComment(StringBuilder buf) { + if ( comment != null ) { + buf.append( "/* " ).append( Dialect.escapeComment( comment ) ).append( " */ " ); + } + } + + private void applyAssignments(StringBuilder buf) { + buf.append( " set " ); + + final Iterator> entries = assignments.entrySet().iterator(); + while ( entries.hasNext() ) { + final Map.Entry entry = entries.next(); + buf.append( entry.getKey() ) + .append( '=' ) + .append( normalizeExpressionFragment( entry.getValue() ) ); + if ( entries.hasNext() ) { + buf.append( ", " ); + } + } + } + + private void applyRestrictions(StringBuilder buf) { + if ( restrictions.isEmpty() ) { + return; + } + + buf.append( " where " ); + + for ( int i = 0; i < restrictions.size(); i++ ) { + if ( i > 0 ) { + buf.append( " and " ); + } + + final Restriction restriction = restrictions.get( i ); + restriction.render( buf, this ); + } + } + + @Override + public String makeParameterMarker() { + return jdbcParameterRenderer.renderJdbcParameter( ++parameterCount, null ); + } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/internal/JdbcParameterRendererStandard.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/internal/JdbcParameterRendererStandard.java index 88b02578a7..c8b5bc5de5 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/internal/JdbcParameterRendererStandard.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/internal/JdbcParameterRendererStandard.java @@ -6,9 +6,7 @@ */ package org.hibernate.sql.ast.internal; -import org.hibernate.dialect.Dialect; import org.hibernate.sql.ast.spi.JdbcParameterRenderer; -import org.hibernate.sql.ast.spi.SqlAppender; import org.hibernate.type.descriptor.jdbc.JdbcType; /** @@ -21,7 +19,7 @@ public class JdbcParameterRendererStandard implements JdbcParameterRenderer { public static final JdbcParameterRendererStandard INSTANCE = new JdbcParameterRendererStandard(); @Override - public void renderJdbcParameter(int position, JdbcType jdbcType, SqlAppender appender, Dialect dialect) { - jdbcType.appendWriteExpression( "?", appender, dialect ); + public String renderJdbcParameter(int position, JdbcType jdbcType) { + return "?"; } } diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java index 059f59006e..f9feae5742 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/AbstractSqlAstTranslator.java @@ -203,6 +203,7 @@ import org.hibernate.type.StandardBasicTypes; import org.hibernate.type.descriptor.WrapperOptions; import org.hibernate.type.descriptor.java.JavaType; import org.hibernate.type.descriptor.jdbc.JdbcLiteralFormatter; +import org.hibernate.type.descriptor.jdbc.JdbcType; import org.hibernate.type.descriptor.sql.DdlType; import org.hibernate.type.descriptor.sql.spi.DdlTypeRegistry; @@ -6191,12 +6192,10 @@ public abstract class AbstractSqlAstTranslator implemen } protected void renderParameterAsParameter(JdbcParameter jdbcParameter, int position) { - jdbcParameterRenderer.renderJdbcParameter( - position, - jdbcParameter.getExpressionType().getJdbcMappings().get( 0 ).getJdbcType(), - this, - getDialect() - ); + final JdbcType jdbcType = jdbcParameter.getExpressionType().getJdbcMappings().get( 0 ).getJdbcType(); + assert jdbcType != null; + final String parameterMarker = jdbcParameterRenderer.renderJdbcParameter( position, jdbcType ); + jdbcType.appendWriteExpression( parameterMarker, this, dialect ); } @Override diff --git a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/JdbcParameterRenderer.java b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/JdbcParameterRenderer.java index f9c8be0ceb..b99a4c0e0d 100644 --- a/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/JdbcParameterRenderer.java +++ b/hibernate-core/src/main/java/org/hibernate/sql/ast/spi/JdbcParameterRenderer.java @@ -6,14 +6,21 @@ */ package org.hibernate.sql.ast.spi; -import org.hibernate.dialect.Dialect; import org.hibernate.service.Service; import org.hibernate.sql.ast.internal.JdbcParameterRendererStandard; import org.hibernate.type.descriptor.jdbc.JdbcType; /** - * Extension point, intended for use from Hibernate Reactive, to render JDBC - * parameter placeholders into the SQL query string being generated. + * Extension point for rendering parameter markers. + *

+ * Generally Hibernate will use the JDBC standard marker - {@code ?}. Many + * databases support alternative marker syntax, often numbered. + *

+ * Originally developed as an extension point for use from Hibernate Reactive + * to handle the fact that some Vert.X drivers (ok, their PGSQL driver) only + * support native parameter marker syntax instead of the JDBC standard + * + * @see org.hibernate.cfg.AvailableSettings#DIALECT_NATIVE_PARAM_MARKERS * * @author Steve Ebersole */ @@ -22,11 +29,9 @@ public interface JdbcParameterRenderer extends Service { * Render the parameter for the given position * * @param position The 1-based position of the parameter. - * @param jdbcType The type of the parameter - * @param appender The appender where the parameter should be rendered - * @param dialect The Dialect in use within the SessionFactory + * @param jdbcType The type of the parameter, if known */ - void renderJdbcParameter(int position, JdbcType jdbcType, SqlAppender appender, Dialect dialect); + String renderJdbcParameter(int position, JdbcType jdbcType); static boolean isStandardRenderer(JdbcParameterRenderer check) { return check == null || JdbcParameterRendererStandard.class.equals( check.getClass() ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetomany/OrderByTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetomany/OrderByTest.java index 8a6e081191..19b2cabb4c 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetomany/OrderByTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/onetomany/OrderByTest.java @@ -297,7 +297,7 @@ public class OrderByTest extends BaseCoreFunctionalTestCase { try { final QueryableCollection queryableCollection = (QueryableCollection) transactionsPersister; - SimpleSelect select = new SimpleSelect( sessionFactory().getJdbcServices().getDialect() ) + SimpleSelect select = new SimpleSelect( sessionFactory() ) .setTableName( queryableCollection.getTableName() ) .addColumn( "code" ) .addColumn( "transactions_index" ); diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/list/PersistentListTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/list/PersistentListTest.java index a1ffcb1834..cf0da63594 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/collection/list/PersistentListTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/collection/list/PersistentListTest.java @@ -72,11 +72,11 @@ public class PersistentListTest { session2.doWork( connection -> { final QueryableCollection queryableCollection = (QueryableCollection) collectionPersister; - SimpleSelect select = new SimpleSelect( sessionFactory.getJdbcServices().getDialect() ) + SimpleSelect select = new SimpleSelect( sessionFactory ) .setTableName( queryableCollection.getTableName() ) .addColumn( "NAME" ) .addColumn( "LIST_INDEX" ) - .addCondition( "NAME", "<>", "?" ); + .addRestriction( "NAME", "<>", "?" ); PreparedStatement preparedStatement = ( (SessionImplementor) session2 ).getJdbcCoordinator() .getStatementPreparer() .prepareStatement( select.toStatementString() ); @@ -133,7 +133,7 @@ public class PersistentListTest { session2.doWork( connection -> { final QueryableCollection queryableCollection = (QueryableCollection) collectionPersister; - SimpleSelect select = new SimpleSelect( sessionFactory.getJdbcServices().getDialect() ) + SimpleSelect select = new SimpleSelect( sessionFactory ) .setTableName( queryableCollection.getTableName() ) .addColumn( "order_id" ) .addColumn( "INDX" ) diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/JdbcParameterRendererTests.java b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/JdbcParameterRendererTests.java index fd2d737b5b..2ebecccacb 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/JdbcParameterRendererTests.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/sql/ast/JdbcParameterRendererTests.java @@ -109,8 +109,8 @@ public class JdbcParameterRendererTests { public static class JdbcParameterRendererImpl implements JdbcParameterRenderer { @Override - public void renderJdbcParameter(int position, JdbcType jdbcType, SqlAppender appender, Dialect dialect) { - jdbcType.appendWriteExpression( "?" + position, appender, dialect ); + public String renderJdbcParameter(int position, JdbcType jdbcType) { + return "?" + position; } } diff --git a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java index 5f57f1c0c3..2de60cf7b2 100644 --- a/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java +++ b/hibernate-envers/src/main/java/org/hibernate/envers/strategy/internal/ValidityAuditStrategy.java @@ -561,7 +561,7 @@ public class ValidityAuditStrategy implements AuditStrategy { final String revEndColumnName = rootAuditEntity.findAttributeMapping( revEndAttributeName ) .getSelectable( 0 ) .getSelectionExpression(); - context.addColumn( revEndColumnName ); + context.addAssignment( revEndColumnName ); context.bind( revisionNumber, revisionEntity.getIdentifierMapping() ); if ( configuration.isRevisionEndTimestampEnabled() ) { @@ -569,22 +569,22 @@ public class ValidityAuditStrategy implements AuditStrategy { final String revEndTimestampAttributeName = configuration.getRevisionEndTimestampFieldName(); final AttributeMapping revEndTimestampAttributeMapping = rootAuditEntity.findAttributeMapping( revEndTimestampAttributeName ); // Apply optional "[, REVEND_TSTMP = ?]" portion of the SQL - context.addColumn( revEndTimestampAttributeMapping.getSelectable( 0 ).getSelectionExpression() ); + context.addAssignment( revEndTimestampAttributeMapping.getSelectable( 0 ).getSelectionExpression() ); context.bind( getRevEndTimestampValue( configuration, revisionTimestamp ), revEndTimestampAttributeMapping ); } // Apply "WHERE (entity_id) = ?" - context.addPrimaryKeyColumns( rootEntity.getIdentifierColumnNames() ); + context.addRestriction( rootEntity.getIdentifierColumnNames() ); context.bind( id, rootEntity.getIdentifierMapping() ); // Apply "AND REV <> ?" // todo (PropertyMapping) : need to be able to handle paths final String path = configuration.getRevisionNumberPath(); - context.addWhereColumn( rootAuditEntity.toColumns( path )[ 0 ], " <> ?" ); + context.addRestriction( rootAuditEntity.toColumns( path )[ 0 ], "<>", "?" ); context.bind( revisionNumber, rootAuditEntity.getPropertyType( path ) ); // Apply "AND REVEND is null" - context.addWhereColumn( revEndColumnName, " is null" ); + context.addNullnessRestriction( revEndColumnName ); return context; } @@ -623,23 +623,23 @@ public class ValidityAuditStrategy implements AuditStrategy { final String revEndTimestampAttributeName = configuration.getRevisionEndTimestampFieldName(); final AttributeMapping revEndTimestampAttributeMapping = auditEntity.findAttributeMapping( revEndTimestampAttributeName ); final String revEndTimestampColumnName = revEndTimestampAttributeMapping.getSelectable( 0 ).getSelectionExpression(); - context.addColumn( revEndTimestampColumnName ); + context.addAssignment( revEndTimestampColumnName ); context.bind( getRevEndTimestampValue( configuration, revisionTimestamp ), revEndTimestampAttributeMapping ); // Apply "WHERE (entity_id) = ? AND REV <> ?" portion of the SQL final Number revisionNumber = getRevisionNumber( configuration, revision ); // Apply "WHERE (entity_id) = ?" - context.addPrimaryKeyColumns( entity.getIdentifierColumnNames() ); + context.addRestriction( entity.getIdentifierColumnNames() ); context.bind( id, entity.getIdentifierType() ); // Apply "AND REV <> ?" // todo (PropertyMapping) : need to be able to handle paths - context.addWhereColumn( configuration.getRevisionFieldName(), " <> ?" ); + context.addRestriction( configuration.getRevisionFieldName(), "<>", "?" ); context.bind( revisionNumber, auditEntity.getPropertyType( configuration.getRevisionNumberPath() ) ); // Apply "AND REVEND_TSTMP is null" - context.addWhereColumn( revEndTimestampColumnName, " is null" ); + context.addNullnessRestriction( revEndTimestampColumnName ); return context; } @@ -664,7 +664,7 @@ public class ValidityAuditStrategy implements AuditStrategy { private final List bindings = new ArrayList<>( 0 ); public UpdateContext(SessionFactoryImplementor sessionFactory) { - super ( sessionFactory.getJdbcServices().getDialect() ); + super ( sessionFactory ); } public List getBindings() {