From 115ddffdbca3e6fc0bc379f0055d00aa77ef839a Mon Sep 17 00:00:00 2001 From: Gavin King Date: Mon, 4 Mar 2024 20:20:03 +0100 Subject: [PATCH] fix constraint name extraction and 'on constraint' on MySQL --- .../dialect/DB2LegacySqlAstTranslator.java | 2 +- .../dialect/H2LegacySqlAstTranslator.java | 2 +- .../dialect/HSQLLegacySqlAstTranslator.java | 2 +- .../MariaDBLegacySqlAstTranslator.java | 2 +- .../dialect/MySQLLegacySqlAstTranslator.java | 4 +-- .../dialect/OracleLegacySqlAstTranslator.java | 2 +- .../SQLServerLegacySqlAstTranslator.java | 2 +- .../SybaseASELegacySqlAstTranslator.java | 2 +- .../dialect/SybaseLegacySqlAstTranslator.java | 2 +- .../dialect/DB2SqlAstTranslator.java | 2 +- .../hibernate/dialect/H2SqlAstTranslator.java | 2 +- .../dialect/HANASqlAstTranslator.java | 2 +- .../dialect/HSQLSqlAstTranslator.java | 2 +- .../dialect/MariaDBSqlAstTranslator.java | 2 +- .../org/hibernate/dialect/MySQLDialect.java | 11 +++++++ .../dialect/MySQLSqlAstTranslator.java | 2 +- .../dialect/OracleSqlAstTranslator.java | 2 +- .../hibernate/dialect/SQLServerDialect.java | 9 +++--- .../dialect/SQLServerSqlAstTranslator.java | 2 +- .../dialect/SybaseASESqlAstTranslator.java | 2 +- .../dialect/SybaseSqlAstTranslator.java | 2 +- .../dialect/TiDBSqlAstTranslator.java | 2 +- .../sql/ast/spi/AbstractSqlAstTranslator.java | 29 +++++++++++-------- .../hql/InsertConflictOnConstraintTest.java | 11 +++++++ 24 files changed, 64 insertions(+), 38 deletions(-) diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java index f5c79bd1ab..9c7dba7a46 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/DB2LegacySqlAstTranslator.java @@ -383,7 +383,7 @@ public class DB2LegacySqlAstTranslator extends Abstract protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java index 01a96ac8e8..f43168433f 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/H2LegacySqlAstTranslator.java @@ -178,7 +178,7 @@ public class H2LegacySqlAstTranslator extends AbstractS protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java index f2aa783be4..79c5fc1e69 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/HSQLLegacySqlAstTranslator.java @@ -84,7 +84,7 @@ public class HSQLLegacySqlAstTranslator extends Abstrac protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacySqlAstTranslator.java index 35e868d3a7..01cf6eb82e 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MariaDBLegacySqlAstTranslator.java @@ -150,7 +150,7 @@ public class MariaDBLegacySqlAstTranslator extends Abst getSql(), getParameterBinders(), getAffectedTableNames(), - null + getUniqueConstraintNameThatMayFail(sqlAst) ); } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacySqlAstTranslator.java index 86326b74b6..ec382f39b6 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/MySQLLegacySqlAstTranslator.java @@ -15,8 +15,6 @@ import org.hibernate.dialect.MySQLSqlAstTranslator; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.internal.util.collections.Stack; import org.hibernate.query.sqm.ComparisonOperator; -import org.hibernate.query.sqm.function.AbstractSqmSelfRenderingFunctionDescriptor; -import org.hibernate.query.sqm.function.SelfRenderingFunctionSqlAstExpression; import org.hibernate.sql.ast.Clause; import org.hibernate.sql.ast.spi.AbstractSqlAstTranslator; import org.hibernate.sql.ast.tree.MutationStatement; @@ -162,7 +160,7 @@ public class MySQLLegacySqlAstTranslator extends Abstra getSql(), getParameterBinders(), getAffectedTableNames(), - null + getUniqueConstraintNameThatMayFail(sqlAst) ); } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java index 9a1f66faeb..434fca00fc 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/OracleLegacySqlAstTranslator.java @@ -113,7 +113,7 @@ public class OracleLegacySqlAstTranslator extends Abstr protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java index e3175f910f..318be8b403 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SQLServerLegacySqlAstTranslator.java @@ -135,7 +135,7 @@ public class SQLServerLegacySqlAstTranslator extends Ab protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java index 8a7f78af0d..811b399ade 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseASELegacySqlAstTranslator.java @@ -130,7 +130,7 @@ public class SybaseASELegacySqlAstTranslator extends Ab protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java index d280f0f5c7..8e4352f39f 100644 --- a/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java +++ b/hibernate-community-dialects/src/main/java/org/hibernate/community/dialect/SybaseLegacySqlAstTranslator.java @@ -87,7 +87,7 @@ public class SybaseLegacySqlAstTranslator extends Abstr protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java index 04413b05e6..ccf72844a6 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/DB2SqlAstTranslator.java @@ -382,7 +382,7 @@ public class DB2SqlAstTranslator extends AbstractSqlAst protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/H2SqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/H2SqlAstTranslator.java index c642e139b0..4bb4a5fd6e 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/H2SqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2SqlAstTranslator.java @@ -174,7 +174,7 @@ public class H2SqlAstTranslator extends SqlAstTranslato protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HANASqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/HANASqlAstTranslator.java index 45f6293603..e8d063f32e 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/HANASqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/HANASqlAstTranslator.java @@ -135,7 +135,7 @@ public class HANASqlAstTranslator extends AbstractSqlAs protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java index e651344803..235a88e7e1 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/HSQLSqlAstTranslator.java @@ -80,7 +80,7 @@ public class HSQLSqlAstTranslator extends AbstractSqlAs protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBSqlAstTranslator.java index 2c5be4001f..302b624fb8 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MariaDBSqlAstTranslator.java @@ -163,7 +163,7 @@ public class MariaDBSqlAstTranslator extends AbstractSq getSql(), getParameterBinders(), getAffectedTableNames(), - null + getUniqueConstraintNameThatMayFail(sqlAst) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java index c396df8e5c..b3ea382378 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLDialect.java @@ -39,6 +39,7 @@ import org.hibernate.engine.jdbc.env.spi.IdentifierHelper; import org.hibernate.engine.jdbc.env.spi.IdentifierHelperBuilder; import org.hibernate.engine.jdbc.env.spi.NameQualifierSupport; import org.hibernate.engine.spi.SessionFactoryImplementor; +import org.hibernate.exception.ConstraintViolationException; import org.hibernate.exception.LockAcquisitionException; import org.hibernate.exception.LockTimeoutException; import org.hibernate.exception.spi.SQLExceptionConversionDelegate; @@ -1200,6 +1201,16 @@ public class MySQLDialect extends Dialect { case 1207: case 1206: return new LockAcquisitionException( message, sqlException, sql ); + case 1062: + // Unique constraint violation + String constraintName = getViolatedConstraintNameExtractor().extractConstraintName(sqlException); + return new ConstraintViolationException( + message, + sqlException, + sql, + ConstraintViolationException.ConstraintKind.UNIQUE, + constraintName + ); } final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException ); diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLSqlAstTranslator.java index c2dbfe0060..bdd27029c5 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/MySQLSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/MySQLSqlAstTranslator.java @@ -224,7 +224,7 @@ public class MySQLSqlAstTranslator extends AbstractSqlA getSql(), getParameterBinders(), getAffectedTableNames(), - null + getUniqueConstraintNameThatMayFail(sqlAst) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java index 39671159f8..4cedb48ed6 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/OracleSqlAstTranslator.java @@ -112,7 +112,7 @@ public class OracleSqlAstTranslator extends SqlAstTrans protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java index b3f947b754..4bb7845c1e 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerDialect.java @@ -708,11 +708,12 @@ public class SQLServerDialect extends AbstractTransactSQLDialect { case 2627: case 2601: String message = sqle.getMessage(); - int i = message.indexOf("unique index "); - if (i>0) { - message = message.substring(i); + if ( message.contains("unique index ") ) { + return extractUsingTemplate( "unique index '", "'", message); + } + else { + return extractUsingTemplate( "'", "'", message); } - return extractUsingTemplate( "'", "'", message); default: return null; } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java index e1be71b4a2..d9c66a3c4f 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SQLServerSqlAstTranslator.java @@ -133,7 +133,7 @@ public class SQLServerSqlAstTranslator extends SqlAstTr protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java index c6ed5ec06b..9647b96113 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASESqlAstTranslator.java @@ -115,7 +115,7 @@ public class SybaseASESqlAstTranslator extends Abstract protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqlAstTranslator.java index 10399925c3..6c2703e111 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseSqlAstTranslator.java @@ -86,7 +86,7 @@ public class SybaseSqlAstTranslator extends AbstractSql protected void visitConflictClause(ConflictClause conflictClause) { if ( conflictClause != null ) { if ( conflictClause.isDoUpdate() && conflictClause.getConstraintName() != null ) { - throw new IllegalQueryOperationException( "Insert conflict do update clause with constraint name is not supported" ); + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); } } } diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/TiDBSqlAstTranslator.java b/hibernate-core/src/main/java/org/hibernate/dialect/TiDBSqlAstTranslator.java index 0827d929ac..7e2ed150b6 100644 --- a/hibernate-core/src/main/java/org/hibernate/dialect/TiDBSqlAstTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/dialect/TiDBSqlAstTranslator.java @@ -166,7 +166,7 @@ public class TiDBSqlAstTranslator extends AbstractSqlAs getSql(), getParameterBinders(), getAffectedTableNames(), - null + getUniqueConstraintNameThatMayFail(sqlAst) ); } 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 bb3cfa46a7..f881b27873 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 @@ -846,26 +846,26 @@ public abstract class AbstractSqlAstTranslator implemen protected JdbcOperationQueryInsert translateInsert(InsertSelectStatement sqlAst) { visitInsertStatement( sqlAst ); + return new JdbcOperationQueryInsertImpl( + getSql(), + getParameterBinders(), + getAffectedTableNames(), + getUniqueConstraintNameThatMayFail(sqlAst) + ); + } + + protected String getUniqueConstraintNameThatMayFail(InsertSelectStatement sqlAst) { final ConflictClause conflictClause = sqlAst.getConflictClause(); - final String uniqueConstraintNameThatMayFail; if ( conflictClause == null || !conflictClause.getConstraintColumnNames().isEmpty() ) { - uniqueConstraintNameThatMayFail = null; + return null; } else { if ( sqlAst.getSourceSelectStatement() != null && !isFetchFirstRowOnly( sqlAst.getSourceSelectStatement() ) || sqlAst.getValuesList().size() > 1 ) { throw new IllegalQueryOperationException( "Can't emulate conflict clause with constraint name for more than one row to insert" ); } - uniqueConstraintNameThatMayFail = conflictClause.getConstraintName() == null - ? "" - : conflictClause.getConstraintName(); + return conflictClause.getConstraintName() == null ? "" : conflictClause.getConstraintName(); } - return new JdbcOperationQueryInsertImpl( - getSql(), - getParameterBinders(), - getAffectedTableNames(), - uniqueConstraintNameThatMayFail - ); } protected JdbcOperationQuerySelect translateSelect(SelectStatement selectStatement) { @@ -2059,7 +2059,12 @@ public abstract class AbstractSqlAstTranslator implemen // propagated, but instead will run the respective conflict action. final String constraintName = conflictClause.getConstraintName(); if ( constraintName != null ) { - throw new IllegalQueryOperationException( "Dialect does not support constraint name in conflict clause" ); + if ( conflictClause.isDoUpdate() ) { + throw new IllegalQueryOperationException( "Insert conflict 'do update' clause with constraint name is not supported" ); + } + else { + return; + } } // final List constraintColumnNames = conflictClause.getConstraintColumnNames(); // if ( !constraintColumnNames.isEmpty() ) { diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertConflictOnConstraintTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertConflictOnConstraintTest.java index 59aa1cc4cb..a5d0aba186 100644 --- a/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertConflictOnConstraintTest.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/query/hql/InsertConflictOnConstraintTest.java @@ -5,6 +5,8 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.Id; import jakarta.persistence.Table; import jakarta.persistence.UniqueConstraint; +import org.hibernate.dialect.H2Dialect; +import org.hibernate.dialect.MySQLDialect; import org.hibernate.dialect.OracleDialect; import org.hibernate.dialect.PostgreSQLDialect; import org.hibernate.dialect.SQLServerDialect; @@ -31,6 +33,7 @@ public class InsertConflictOnConstraintTest { @RequiresDialect( PostgreSQLDialect.class ) @RequiresDialect( OracleDialect.class ) @RequiresDialect( SQLServerDialect.class ) + @RequiresDialect( MySQLDialect.class ) @Test void testDoNothing(SessionFactoryScope scope) { scope.getSessionFactory().getSchemaManager().truncateMappedObjects(); scope.inTransaction( s -> s.persist(new Constrained())); @@ -38,6 +41,14 @@ public class InsertConflictOnConstraintTest { scope.inSession( s -> assertEquals(69, s.createSelectionQuery("select count from Constrained", int.class).getSingleResult())); } + @RequiresDialect( H2Dialect.class ) + @Test void testDoNothing2(SessionFactoryScope scope) { + scope.getSessionFactory().getSchemaManager().truncateMappedObjects(); + scope.inTransaction( s -> s.persist(new Constrained())); + scope.inTransaction( s -> s.createMutationQuery("insert into Constrained(id, name, count) values (4,'Gavin',69) on conflict on constraint count_name_key_index_2 do nothing").executeUpdate()); + scope.inSession( s -> assertEquals(69, s.createSelectionQuery("select count from Constrained", int.class).getSingleResult())); + } + @Entity(name = "Constrained") @Table(uniqueConstraints = @UniqueConstraint(name = "count_name_key", columnNames = {"count","name"})) static class Constrained {