HHH-7357 - Constraint violation exception while inserting NULL to not nullable column
This commit is contained in:
parent
6d6dcdf267
commit
bd315f01a9
|
@ -30,6 +30,7 @@ import org.hibernate.dialect.function.AvgWithArgumentCastFunction;
|
|||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
import org.hibernate.dialect.function.VarArgsSQLFunction;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
|
||||
|
@ -313,6 +314,12 @@ public class H2Dialect extends Dialect {
|
|||
exception = new PessimisticLockException(message, sqlException, sql);
|
||||
}
|
||||
|
||||
if ( 90006 == errorCode ) {
|
||||
// NULL not allowed for column [90006-145]
|
||||
final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException );
|
||||
exception = new ConstraintViolationException( message, sqlException, sql, constraintName );
|
||||
}
|
||||
|
||||
return exception;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -37,6 +37,7 @@ import org.hibernate.dialect.function.NvlFunction;
|
|||
import org.hibernate.dialect.function.SQLFunctionTemplate;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
import org.hibernate.dialect.function.VarArgsSQLFunction;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.hibernate.exception.LockTimeoutException;
|
||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
|
@ -462,6 +463,14 @@ public class Oracle8iDialect extends Dialect {
|
|||
}
|
||||
|
||||
|
||||
// data integrity violation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
if ( 1407 == errorCode ) {
|
||||
// ORA-01407: cannot update column to NULL
|
||||
final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException );
|
||||
return new ConstraintViolationException( message, sqlException, sql, constraintName );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.hibernate.LockMode;
|
|||
import org.hibernate.LockOptions;
|
||||
import org.hibernate.QueryTimeoutException;
|
||||
import org.hibernate.dialect.function.SQLFunctionTemplate;
|
||||
import org.hibernate.exception.ConstraintViolationException;
|
||||
import org.hibernate.exception.LockAcquisitionException;
|
||||
import org.hibernate.exception.LockTimeoutException;
|
||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
|
@ -104,9 +105,15 @@ public class SybaseASE157Dialect extends SybaseASE15Dialect {
|
|||
@Override
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
|
||||
if("JZ0TO".equals( sqlState ) || "JZ006".equals( sqlState )){
|
||||
throw new LockTimeoutException( message, sqlException, sql );
|
||||
}
|
||||
if ( 515 == errorCode && "ZZZZZ".equals( sqlState ) ) {
|
||||
// Attempt to insert NULL value into column; column does not allow nulls.
|
||||
final String constraintName = getViolatedConstraintNameExtracter().extractConstraintName( sqlException );
|
||||
return new ConstraintViolationException( message, sqlException, sql, constraintName );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -112,7 +112,8 @@ public class SQLStateConversionDelegate extends AbstractSQLExceptionConversionDe
|
|||
|
||||
@Override
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
|
||||
|
||||
if ( sqlState != null ) {
|
||||
String sqlStateClassCode = JdbcExceptionHelper.determineSqlStateClassCode( sqlState );
|
||||
|
@ -146,8 +147,8 @@ public class SQLStateConversionDelegate extends AbstractSQLExceptionConversionDe
|
|||
|
||||
// MySQL Query execution was interrupted
|
||||
if ( "70100".equals( sqlState ) ||
|
||||
// Oracle user requested cancel of current operation
|
||||
"72000".equals( sqlState ) ) {
|
||||
// Oracle user requested cancel of current operation
|
||||
( "72000".equals( sqlState ) && errorCode == 1013 ) ) {
|
||||
throw new QueryTimeoutException( message, sqlException, sql );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,16 +26,21 @@ package org.hibernate.test.exception;
|
|||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.dialect.MySQLMyISAMDialect;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
|
||||
import org.hibernate.engine.jdbc.spi.ResultSetReturn;
|
||||
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;
|
||||
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
@ -78,14 +83,7 @@ public class SQLExceptionConversionTest extends BaseCoreFunctionalTestCase {
|
|||
// expected outcome
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
try {
|
||||
((SessionImplementor)session).getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
// ignore...
|
||||
}
|
||||
}
|
||||
releaseStatement( session, ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,14 +114,7 @@ public class SQLExceptionConversionTest extends BaseCoreFunctionalTestCase {
|
|||
// expected outcome
|
||||
}
|
||||
finally {
|
||||
if ( ps != null ) {
|
||||
try {
|
||||
((SessionImplementor)session).getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
}
|
||||
catch( Throwable ignore ) {
|
||||
// ignore...
|
||||
}
|
||||
}
|
||||
releaseStatement( session, ps );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -132,4 +123,56 @@ public class SQLExceptionConversionTest extends BaseCoreFunctionalTestCase {
|
|||
session.getTransaction().rollback();
|
||||
session.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestForIssue(jiraKey = "HHH-7357")
|
||||
public void testNotNullConstraint() {
|
||||
final Session session = openSession();
|
||||
session.beginTransaction();
|
||||
|
||||
final User user = new User();
|
||||
user.setUsername( "Lukasz" );
|
||||
session.save( user );
|
||||
session.flush();
|
||||
|
||||
session.doWork(
|
||||
new Work() {
|
||||
@Override
|
||||
public void execute(Connection connection) throws SQLException {
|
||||
final JdbcCoordinator jdbcCoordinator = ( (SessionImplementor) session ).getTransactionCoordinator().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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
session.getTransaction().rollback();
|
||||
session.close();
|
||||
}
|
||||
|
||||
private void releaseStatement(Session session, PreparedStatement ps) {
|
||||
if ( ps != null ) {
|
||||
try {
|
||||
( (SessionImplementor) session ).getTransactionCoordinator().getJdbcCoordinator().release( ps );
|
||||
}
|
||||
catch ( Throwable ignore ) {
|
||||
// ignore...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<id name="id" unsaved-value="null" column="user_id" >
|
||||
<generator class="native"/>
|
||||
</id>
|
||||
<property name="username" type="string" column="user_name" />
|
||||
<property name="username" type="string" column="user_name" not-null="true" />
|
||||
<set name="memberships" inverse="false" table="T_MEMBERSHIP" cascade="none">
|
||||
<key column="user_id"/>
|
||||
<many-to-many class="Group" column="group_id"/>
|
||||
|
|
Loading…
Reference in New Issue