HHH-7298 - regression, org.hibernate.ejb.test.lock.LockTest
This commit is contained in:
parent
007bbe45a9
commit
070ee532f5
|
@ -22,14 +22,19 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.dialect;
|
||||
|
||||
import java.sql.CallableStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Types;
|
||||
|
||||
import org.hibernate.JDBCException;
|
||||
import org.hibernate.cfg.Environment;
|
||||
import org.hibernate.dialect.function.NoArgSQLFunction;
|
||||
import org.hibernate.dialect.function.StandardSQLFunction;
|
||||
import org.hibernate.exception.LockTimeoutException;
|
||||
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
|
||||
import org.hibernate.internal.util.JdbcExceptionHelper;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.type.StandardBasicTypes;
|
||||
|
||||
|
@ -237,10 +242,7 @@ public class MySQLDialect extends Dialect {
|
|||
}
|
||||
|
||||
public String getLimitString(String sql, boolean hasOffset) {
|
||||
return new StringBuilder( sql.length() + 20 )
|
||||
.append( sql )
|
||||
.append( hasOffset ? " limit ?, ?" : " limit ?" )
|
||||
.toString();
|
||||
return sql + (hasOffset ? " limit ?, ?" : " limit ?");
|
||||
}
|
||||
|
||||
public char closeQuote() {
|
||||
|
@ -366,4 +368,29 @@ public class MySQLDialect extends Dialect {
|
|||
public boolean supportsSubqueryOnMutatingTable() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsLockTimeouts() {
|
||||
// yes, we do handle "lock timeout" conditions in the exception conversion delegate,
|
||||
// but that's a hardcoded lock timeout period across the whole entire MySQL database.
|
||||
// MySQL does not support specifying lock timeouts as part of the SQL statement, which is really
|
||||
// what this meta method is asking.
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
return new SQLExceptionConversionDelegate() {
|
||||
@Override
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
|
||||
if ( "41000".equals( sqlState ) ) {
|
||||
return new LockTimeoutException( message, sqlException, sql );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -373,30 +373,23 @@ public class PostgreSQL81Dialect extends Dialect {
|
|||
|
||||
@Override
|
||||
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
|
||||
SQLExceptionConversionDelegate delegate = super.buildSQLExceptionConversionDelegate();
|
||||
if (delegate == null) {
|
||||
delegate = new SQLExceptionConversionDelegate() {
|
||||
@Override
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
JDBCException exception = null;
|
||||
|
||||
if (exception == null) {
|
||||
String sqlState = JdbcExceptionHelper.extractSqlState(sqlException);
|
||||
|
||||
if ("40P01".equals(sqlState)) { // DEADLOCK DETECTED
|
||||
exception = new LockAcquisitionException(message, sqlException, sql);
|
||||
}
|
||||
|
||||
if ("55P03".equals(sqlState)) { // LOCK NOT AVAILABLE
|
||||
exception = new PessimisticLockException(message, sqlException, sql);
|
||||
}
|
||||
}
|
||||
|
||||
return exception;
|
||||
return new SQLExceptionConversionDelegate() {
|
||||
@Override
|
||||
public JDBCException convert(SQLException sqlException, String message, String sql) {
|
||||
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
|
||||
|
||||
if ( "40P01".equals( sqlState ) ) { // DEADLOCK DETECTED
|
||||
return new LockAcquisitionException( message, sqlException, sql );
|
||||
}
|
||||
};
|
||||
}
|
||||
return delegate;
|
||||
|
||||
if ( "55P03".equals( sqlState ) ) { // LOCK NOT AVAILABLE
|
||||
return new PessimisticLockException( message, sqlException, sql );
|
||||
}
|
||||
|
||||
// returning null allows other delegates to operate
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2012, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @author tags or express copyright attribution
|
||||
* statements applied by the authors. All third-party contributions are
|
||||
* distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.exception;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class LockTimeoutException extends LockAcquisitionException {
|
||||
public LockTimeoutException(String string, SQLException root) {
|
||||
super( string, root );
|
||||
}
|
||||
|
||||
public LockTimeoutException(String string, SQLException root, String sql) {
|
||||
super( string, root, sql );
|
||||
}
|
||||
}
|
|
@ -1320,6 +1320,11 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
handlePersistenceException( converted );
|
||||
return converted;
|
||||
}
|
||||
else if ( e instanceof org.hibernate.exception.LockTimeoutException ) {
|
||||
PersistenceException converted = wrapLockException( e, lockOptions );
|
||||
handlePersistenceException( converted );
|
||||
return converted;
|
||||
}
|
||||
else if ( e instanceof org.hibernate.PessimisticLockException ) {
|
||||
PersistenceException converted = wrapLockException( e, lockOptions );
|
||||
handlePersistenceException( converted );
|
||||
|
@ -1416,6 +1421,9 @@ public abstract class AbstractEntityManagerImpl implements HibernateEntityManage
|
|||
final OptimisticEntityLockException lockException = (OptimisticEntityLockException) e;
|
||||
pe = new OptimisticLockException( lockException.getMessage(), lockException, lockException.getEntity() );
|
||||
}
|
||||
else if ( e instanceof org.hibernate.exception.LockTimeoutException ) {
|
||||
pe = new LockTimeoutException( e.getMessage(), e, null );
|
||||
}
|
||||
else if ( e instanceof PessimisticEntityLockException ) {
|
||||
PessimisticEntityLockException lockException = (PessimisticEntityLockException) e;
|
||||
if ( lockOptions != null && lockOptions.getTimeOut() > -1 ) {
|
||||
|
|
|
@ -101,20 +101,25 @@ public class LockTest extends BaseEntityManagerFunctionalTestCase {
|
|||
em3.getTransaction().begin();
|
||||
try {
|
||||
em3.find( Lock.class, lock.getId(), LockModeType.PESSIMISTIC_WRITE, properties );
|
||||
assertFalse("Exception should be thrown", true);
|
||||
} catch (LockTimeoutException lte) {
|
||||
assertTrue("Proper exception thrown for dialect supporting lock timeouts when an immediate timeout is set.", true);
|
||||
} catch (PessimisticLockException pe) {
|
||||
assertTrue("Find with immediate timeout should have thrown LockTimeoutException.", false);
|
||||
} catch (PersistenceException pe) {
|
||||
fail( "Exception should be thrown" );
|
||||
}
|
||||
catch (LockTimeoutException lte) {
|
||||
// Proper exception thrown for dialect supporting lock timeouts when an immediate timeout is set.
|
||||
}
|
||||
catch (PessimisticLockException pe) {
|
||||
fail( "Find with immediate timeout should have thrown LockTimeoutException." );
|
||||
}
|
||||
catch (PersistenceException pe) {
|
||||
log.info("EntityManager.find() for PESSIMISTIC_WRITE with timeout of 0 threw a PersistenceException.\n" +
|
||||
"This is likely a consequence of " + getDialect().getClass().getName() + " not properly mapping SQL errors into the correct HibernateException subtypes.\n" +
|
||||
"See HHH-7251 for an example of one such situation.", pe);
|
||||
assertTrue("EntityManager should be throwing LockTimeoutException.", false);
|
||||
} finally {
|
||||
fail( "EntityManager should be throwing LockTimeoutException." );
|
||||
}
|
||||
finally {
|
||||
if (em3.getTransaction().getRollbackOnly()) {
|
||||
em3.getTransaction().rollback();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
em3.getTransaction().commit();
|
||||
}
|
||||
em3.close();
|
||||
|
|
Loading…
Reference in New Issue