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 9adc838f0b..288e205985 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java
@@ -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;
}
};
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
index 123e38e249..5a0d243feb 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/Oracle8iDialect.java
@@ -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;
}
};
diff --git a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java
index dc9a08b50e..1096672ecd 100644
--- a/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java
+++ b/hibernate-core/src/main/java/org/hibernate/dialect/SybaseASE157Dialect.java
@@ -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;
}
};
diff --git a/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java b/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java
index f92c37929b..b7a5ac2659 100644
--- a/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java
+++ b/hibernate-core/src/main/java/org/hibernate/exception/internal/SQLStateConversionDelegate.java
@@ -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 );
}
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java b/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java
index c3ce0b3ef5..811f8edc63 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java
+++ b/hibernate-core/src/test/java/org/hibernate/test/exception/SQLExceptionConversionTest.java
@@ -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...
+ }
+ }
+ }
}
diff --git a/hibernate-core/src/test/java/org/hibernate/test/exception/User.hbm.xml b/hibernate-core/src/test/java/org/hibernate/test/exception/User.hbm.xml
index a18408ddac..110e5635c5 100644
--- a/hibernate-core/src/test/java/org/hibernate/test/exception/User.hbm.xml
+++ b/hibernate-core/src/test/java/org/hibernate/test/exception/User.hbm.xml
@@ -6,7 +6,7 @@
-
+