/* * 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.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.AbstractHANADialect; 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; /** * Implementation of SQLExceptionConversionTest. * * @author Steve Ebersole */ public class SQLExceptionConversionTest extends BaseCoreFunctionalTestCase { public String[] getMappings() { return new String[] {"exception/User.hbm.xml", "exception/Group.hbm.xml"}; } @Test @SkipForDialect( value = { MySQLMyISAMDialect.class, AbstractHANADialect.class }, comment = "MySQL (MyISAM) / Hana do not support FK violation checking" ) public void testIntegrityViolation() throws Exception { 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 ); fail("INSERT should have failed"); } catch (ConstraintViolationException ignore) { // expected outcome } finally { releaseStatement( session, ps ); } } } ); session.getTransaction().rollback(); session.close(); } @Test public void testBadGrammar() throws Exception { 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 ); fail("SQL compilation should have failed"); } catch (SQLGrammarException ignored) { // expected outcome } finally { releaseStatement( session, ps ); } } } ); 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 ).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 ).getJdbcCoordinator().getResourceRegistry().release( ps ); } catch ( Throwable ignore ) { // ignore... } } } }