fix for Dialects with null SQLException delegate

This commit is contained in:
Gavin King 2022-01-25 22:47:58 +01:00
parent 6b5c11b1ff
commit 5dbf9aedf9
2 changed files with 54 additions and 67 deletions

View File

@ -28,6 +28,7 @@ import org.hibernate.engine.jdbc.spi.SqlExceptionHelper;
import org.hibernate.exception.internal.SQLExceptionTypeDelegate;
import org.hibernate.exception.internal.SQLStateConversionDelegate;
import org.hibernate.exception.internal.StandardSQLExceptionConverter;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.ServiceRegistryImplementor;
import org.hibernate.sql.ast.SqlAstTranslatorFactory;
@ -335,13 +336,11 @@ public class JdbcEnvironmentImpl implements JdbcEnvironment {
}
private SqlExceptionHelper buildSqlExceptionHelper(Dialect dialect, boolean logWarnings) {
final StandardSQLExceptionConverter sqlExceptionConverter = new StandardSQLExceptionConverter(
dialect.buildSQLExceptionConversionDelegate(),
new SQLExceptionTypeDelegate( dialect ),
// todo : vary this based on extractedMetaDataSupport.getSqlStateType()
new SQLStateConversionDelegate( dialect )
);
return new SqlExceptionHelper( sqlExceptionConverter, logWarnings );
SQLExceptionConversionDelegate dialectDelegate = dialect.buildSQLExceptionConversionDelegate();
SQLExceptionConversionDelegate[] delegates = dialectDelegate == null
? new SQLExceptionConversionDelegate[] { new SQLExceptionTypeDelegate( dialect ), new SQLStateConversionDelegate( dialect ) }
: new SQLExceptionConversionDelegate[] { dialectDelegate, new SQLExceptionTypeDelegate( dialect ), new SQLStateConversionDelegate( dialect ) };
return new SqlExceptionHelper( new StandardSQLExceptionConverter(delegates), logWarnings );
}
@Override

View File

@ -6,9 +6,7 @@
*/
package org.hibernate.orm.test.exception;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Types;
import org.hibernate.Session;
@ -20,7 +18,6 @@ import org.hibernate.engine.jdbc.spi.StatementPreparer;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.exception.ConstraintViolationException;
import org.hibernate.exception.SQLGrammarException;
import org.hibernate.jdbc.Work;
import org.hibernate.testing.SkipForDialect;
import org.hibernate.testing.TestForIssue;
@ -51,31 +48,28 @@ public class SQLExceptionConversionTest extends BaseCoreFunctionalTestCase {
value = { AbstractHANADialect.class, TiDBDialect.class},
comment = "MySQL (MyISAM) / Hana / TiDB do not support FK violation checking"
)
public void testIntegrityViolation() throws Exception {
public void testIntegrityViolation() {
final Session session = openSession();
session.beginTransaction();
session.doWork(
new Work() {
@Override
public void execute(Connection connection) throws SQLException {
// Attempt to insert some bad values into the T_MEMBERSHIP table that should
// result in a constraint violation
PreparedStatement ps = null;
try {
ps = ((SessionImplementor)session).getJdbcCoordinator().getStatementPreparer().prepareStatement( "INSERT INTO T_MEMBERSHIP (user_id, group_id) VALUES (?, ?)" );
ps.setLong(1, 52134241); // Non-existent user_id
ps.setLong(2, 5342); // Non-existent group_id
((SessionImplementor)session).getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
connection -> {
// Attempt to insert some bad values into the T_MEMBERSHIP table that should
// result in a constraint violation
PreparedStatement ps = null;
try {
ps = ((SessionImplementor)session).getJdbcCoordinator().getStatementPreparer().prepareStatement( "INSERT INTO T_MEMBERSHIP (user_id, group_id) VALUES (?, ?)" );
ps.setLong(1, 52134241); // Non-existent user_id
ps.setLong(2, 5342); // Non-existent group_id
((SessionImplementor)session).getJdbcCoordinator().getResultSetReturn().executeUpdate( ps );
fail("INSERT should have failed");
}
catch (ConstraintViolationException ignore) {
// expected outcome
}
finally {
releaseStatement( session, ps );
}
fail("INSERT should have failed");
}
catch (ConstraintViolationException ignore) {
// expected outcome
}
finally {
releaseStatement( session, ps );
}
}
);
@ -85,28 +79,25 @@ public class SQLExceptionConversionTest extends BaseCoreFunctionalTestCase {
}
@Test
public void testBadGrammar() throws Exception {
public void testBadGrammar() {
final Session session = openSession();
session.beginTransaction();
session.doWork(
new Work() {
@Override
public void execute(Connection connection) throws SQLException {
// prepare/execute a query against a non-existent table
PreparedStatement ps = null;
try {
ps = ((SessionImplementor)session).getJdbcCoordinator().getStatementPreparer().prepareStatement( "SELECT user_id, user_name FROM tbl_no_there" );
((SessionImplementor)session).getJdbcCoordinator().getResultSetReturn().extract( ps );
connection -> {
// prepare/execute a query against a non-existent table
PreparedStatement ps = null;
try {
ps = ((SessionImplementor)session).getJdbcCoordinator().getStatementPreparer().prepareStatement( "SELECT user_id, user_name FROM tbl_no_there" );
((SessionImplementor)session).getJdbcCoordinator().getResultSetReturn().extract( ps );
fail("SQL compilation should have failed");
}
catch (SQLGrammarException ignored) {
// expected outcome
}
finally {
releaseStatement( session, ps );
}
fail("SQL compilation should have failed");
}
catch (SQLGrammarException ignored) {
// expected outcome
}
finally {
releaseStatement( session, ps );
}
}
);
@ -127,27 +118,24 @@ public class SQLExceptionConversionTest extends BaseCoreFunctionalTestCase {
session.flush();
session.doWork(
new Work() {
@Override
public void execute(Connection connection) throws SQLException {
final JdbcCoordinator jdbcCoordinator = ( (SessionImplementor) session ).getJdbcCoordinator();
final StatementPreparer statementPreparer = jdbcCoordinator.getStatementPreparer();
final ResultSetReturn resultSetReturn = jdbcCoordinator.getResultSetReturn();
PreparedStatement ps = null;
try {
ps = statementPreparer.prepareStatement( "UPDATE T_USER SET user_name = ? WHERE user_id = ?" );
ps.setNull( 1, Types.VARCHAR ); // Attempt to update user name to NULL (NOT NULL constraint defined).
ps.setLong( 2, user.getId() );
resultSetReturn.executeUpdate( ps );
connection -> {
final JdbcCoordinator jdbcCoordinator = ( (SessionImplementor) session ).getJdbcCoordinator();
final StatementPreparer statementPreparer = jdbcCoordinator.getStatementPreparer();
final ResultSetReturn resultSetReturn = jdbcCoordinator.getResultSetReturn();
PreparedStatement ps = null;
try {
ps = statementPreparer.prepareStatement( "UPDATE T_USER SET user_name = ? WHERE user_id = ?" );
ps.setNull( 1, Types.VARCHAR ); // Attempt to update user name to NULL (NOT NULL constraint defined).
ps.setLong( 2, user.getId() );
resultSetReturn.executeUpdate( ps );
fail( "UPDATE should have failed because of not NULL constraint." );
}
catch ( ConstraintViolationException ignore ) {
// expected outcome
}
finally {
releaseStatement( session, ps );
}
fail( "UPDATE should have failed because of not NULL constraint." );
}
catch ( ConstraintViolationException ignore ) {
// expected outcome
}
finally {
releaseStatement( session, ps );
}
}
);