HHH-7298 regression, org.hibernate.ejb.test.lock.LockTest

This commit is contained in:
Strong Liu 2012-05-31 01:00:39 +08:00
parent 29103357a9
commit 2b213dabc3
7 changed files with 149 additions and 60 deletions

View File

@ -28,6 +28,7 @@ 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.AnsiTrimEmulationFunction;
import org.hibernate.dialect.function.AvgWithArgumentCastFunction;
@ -35,6 +36,9 @@ import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.descriptor.sql.SmallIntTypeDescriptor;
import org.hibernate.type.descriptor.sql.SqlTypeDescriptor;
@ -427,4 +431,21 @@ public class DB2Dialect extends Dialect {
protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
return sqlCode == Types.BOOLEAN ? SmallIntTypeDescriptor.INSTANCE : super.getSqlTypeDescriptorOverride( sqlCode );
}
@Override
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
return new SQLExceptionConversionDelegate() {
@Override
public JDBCException convert(SQLException sqlException, String message, String sql) {
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException );
if( -952 == errorCode && "57014".equals( sqlState )){
throw new LockTimeoutException( message, sqlException, sql );
}
return null;
}
};
}
}

View File

@ -32,6 +32,7 @@ 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.LockAcquisitionException;
import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.internal.util.JdbcExceptionHelper;
@ -292,17 +293,15 @@ public class MySQLDialect extends Dialect {
}
public String getCastTypeName(int code) {
if ( code==Types.INTEGER ) {
return "signed";
}
else if ( code==Types.VARCHAR ) {
return "char";
}
else if ( code==Types.VARBINARY ) {
return "binary";
}
else {
return super.getCastTypeName( code );
switch ( code ){
case Types.INTEGER:
return "signed";
case Types.VARCHAR:
return "char";
case Types.VARBINARY:
return "binary";
default:
return super.getCastTypeName( code );
}
}
@ -389,6 +388,10 @@ public class MySQLDialect extends Dialect {
return new LockTimeoutException( message, sqlException, sql );
}
if ( "40001".equals( sqlState ) ) {
return new LockAcquisitionException( message, sqlException, sql );
}
return null;
}
};

View File

@ -65,11 +65,8 @@ public class Oracle8iDialect extends Dialect {
registerNumericTypeMappings();
registerDateTimeTypeMappings();
registerLargeObjectTypeMappings();
registerReverseHibernateTypeMappings();
registerFunctions();
registerDefaultProperties();
}
@ -221,6 +218,7 @@ public class Oracle8iDialect extends Dialect {
*
* @return The orqacle join fragment
*/
@Override
public JoinFragment createOuterJoinFragment() {
return new OracleJoinFragment();
}
@ -228,6 +226,7 @@ public class Oracle8iDialect extends Dialect {
/**
* {@inheritDoc}
*/
@Override
public String getCrossJoinSeparator() {
return ", ";
}
@ -238,10 +237,11 @@ public class Oracle8iDialect extends Dialect {
*
* @return The oracle CASE -> DECODE fragment
*/
@Override
public CaseFragment createCaseFragment() {
return new DecodeCaseFragment();
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
sql = sql.trim();
boolean isForUpdate = false;
@ -282,7 +282,7 @@ public class Oracle8iDialect extends Dialect {
public String getBasicSelectClauseNullString(int sqlType) {
return super.getSelectClauseNullString( sqlType );
}
@Override
public String getSelectClauseNullString(int sqlType) {
switch(sqlType) {
case Types.VARCHAR:
@ -296,82 +296,82 @@ public class Oracle8iDialect extends Dialect {
return "to_number(null)";
}
}
@Override
public String getCurrentTimestampSelectString() {
return "select sysdate from dual";
}
@Override
public String getCurrentTimestampSQLFunctionName() {
return "sysdate";
}
// features which remain constant across 8i, 9i, and 10g ~~~~~~~~~~~~~~~~~~
@Override
public String getAddColumnString() {
return "add";
}
@Override
public String getSequenceNextValString(String sequenceName) {
return "select " + getSelectSequenceNextValString( sequenceName ) + " from dual";
}
@Override
public String getSelectSequenceNextValString(String sequenceName) {
return sequenceName + ".nextval";
}
@Override
public String getCreateSequenceString(String sequenceName) {
return "create sequence " + sequenceName; //starts with 1, implicitly
}
@Override
public String getDropSequenceString(String sequenceName) {
return "drop sequence " + sequenceName;
}
@Override
public String getCascadeConstraintsString() {
return " cascade constraints";
}
@Override
public boolean dropConstraints() {
return false;
}
@Override
public String getForUpdateNowaitString() {
return " for update nowait";
}
@Override
public boolean supportsSequences() {
return true;
}
@Override
public boolean supportsPooledSequences() {
return true;
}
@Override
public boolean supportsLimit() {
return true;
}
@Override
public String getForUpdateString(String aliases) {
return getForUpdateString() + " of " + aliases;
}
@Override
public String getForUpdateNowaitString(String aliases) {
return getForUpdateString() + " of " + aliases + " nowait";
}
@Override
public boolean bindLimitParametersInReverseOrder() {
return true;
}
@Override
public boolean useMaxForLimit() {
return true;
}
@Override
public boolean forUpdateOfColumns() {
return true;
}
@Override
public String getQuerySequencesString() {
return " select sequence_name from all_sequences"
+ " union"
@ -380,11 +380,11 @@ public class Oracle8iDialect extends Dialect {
+ " where asq.sequence_name = us.table_name"
+ " and asq.sequence_owner = us.table_owner";
}
@Override
public String getSelectGUIDString() {
return "select rawtohex(sys_guid()) from dual";
}
@Override
public ViolatedConstraintNameExtracter getViolatedConstraintNameExtracter() {
return EXTRACTER;
}
@ -501,63 +501,63 @@ public class Oracle8iDialect extends Dialect {
throw new HibernateException( "Unable to access OracleTypes.CURSOR value", se );
}
}
@Override
public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
// register the type of the out param - an Oracle specific type
statement.registerOutParameter( col, getOracleCursorTypeSqlType() );
col++;
return col;
}
@Override
public ResultSet getResultSet(CallableStatement ps) throws SQLException {
ps.execute();
return ( ResultSet ) ps.getObject( 1 );
}
@Override
public boolean supportsUnionAll() {
return true;
}
@Override
public boolean supportsCommentOn() {
return true;
}
@Override
public boolean supportsTemporaryTables() {
return true;
}
@Override
public String generateTemporaryTableName(String baseTableName) {
String name = super.generateTemporaryTableName(baseTableName);
return name.length() > 30 ? name.substring( 1, 30 ) : name;
}
@Override
public String getCreateTemporaryTableString() {
return "create global temporary table";
}
@Override
public String getCreateTemporaryTablePostfix() {
return "on commit delete rows";
}
@Override
public boolean dropTemporaryTableAfterUse() {
return false;
}
@Override
public boolean supportsCurrentTimestampSelection() {
return true;
}
@Override
public boolean isCurrentTimestampSelectStringCallable() {
return false;
}
// Overridden informational metadata ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@Override
public boolean supportsEmptyInList() {
return false;
}
@Override
public boolean supportsExistsInSelect() {
return false;
}

View File

@ -36,23 +36,24 @@ import org.hibernate.sql.CaseFragment;
* @author Steve Ebersole
*/
public class Oracle9iDialect extends Oracle8iDialect {
@Override
protected void registerCharacterTypeMappings() {
registerColumnType( Types.CHAR, "char(1 char)" );
registerColumnType( Types.VARCHAR, 4000, "varchar2($l char)" );
registerColumnType( Types.VARCHAR, "long" );
}
@Override
protected void registerDateTimeTypeMappings() {
registerColumnType( Types.DATE, "date" );
registerColumnType( Types.TIME, "date" );
registerColumnType( Types.TIMESTAMP, "timestamp" );
}
@Override
public CaseFragment createCaseFragment() {
// Oracle did add support for ANSI CASE statements in 9i
return new ANSICaseFragment();
}
@Override
public String getLimitString(String sql, boolean hasOffset) {
sql = sql.trim();
String forUpdateClause = null;
@ -87,25 +88,26 @@ public class Oracle9iDialect extends Oracle8iDialect {
return pagingSelect.toString();
}
@Override
public String getSelectClauseNullString(int sqlType) {
return getBasicSelectClauseNullString( sqlType );
}
@Override
public String getCurrentTimestampSelectString() {
return "select systimestamp from dual";
}
@Override
public String getCurrentTimestampSQLFunctionName() {
// the standard SQL function name is current_timestamp...
return "current_timestamp";
}
// locking support
@Override
public String getForUpdateString() {
return " for update";
}
@Override
public String getWriteLockString(int timeout) {
if ( timeout == LockOptions.NO_WAIT ) {
return " for update nowait";
@ -119,7 +121,7 @@ public class Oracle9iDialect extends Oracle8iDialect {
else
return " for update";
}
@Override
public String getReadLockString(int timeout) {
return getWriteLockString( timeout );
}
@ -127,10 +129,11 @@ public class Oracle9iDialect extends Oracle8iDialect {
* HHH-4907, I don't know if oracle 8 supports this syntax, so I'd think it is better add this
* method here. Reopen this issue if you found/know 8 supports it.
*/
@Override
public boolean supportsRowValueConstructorSyntaxInInList() {
return true;
}
@Override
public boolean supportsTupleDistinctCounts() {
return false;
}

View File

@ -23,12 +23,18 @@
*/
package org.hibernate.dialect;
import java.sql.SQLException;
import java.sql.Types;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.hibernate.JDBCException;
import org.hibernate.LockMode;
import org.hibernate.QueryTimeoutException;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.type.StandardBasicTypes;
/**
@ -258,4 +264,19 @@ public class SQLServer2005Dialect extends SQLServerDialect {
} while ( cur < len && depth != 0 && pos != -1 );
return depth == 0 ? pos : -1;
}
@Override
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
return new SQLExceptionConversionDelegate() {
@Override
public JDBCException convert(SQLException sqlException, String message, String sql) {
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
if( "HY008".equals( sqlState )){
throw new QueryTimeoutException( message, sqlException, sql );
}
return null;
}
};
}
}

View File

@ -23,11 +23,20 @@
*/
package org.hibernate.dialect;
import java.sql.SQLException;
import java.util.Map;
import org.hibernate.JDBCException;
import org.hibernate.LockMode;
import org.hibernate.LockOptions;
import org.hibernate.QueryTimeoutException;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.LockTimeoutException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.sql.ForUpdateFragment;
import org.hibernate.type.StandardBasicTypes;
@ -50,6 +59,18 @@ public class SybaseASE157Dialect extends SybaseASE15Dialect {
registerFunction( "charindex", new SQLFunctionTemplate( StandardBasicTypes.INTEGER, "charindex(?1, ?2, ?3)" ) );
}
//HHH-7298 I don't know if this would break something or cause some side affects
//but it is required to use 'select for update'
@Override
public String getTableTypeString() {
return " lock datarows";
}
@Override
public boolean supportsLockTimeouts() {
return true;
}
// support Lob Locator
public boolean supportsExpectedLobUsagePattern() {
return true;
@ -79,5 +100,20 @@ public class SybaseASE157Dialect extends SybaseASE15Dialect {
public String applyLocksToSql(String sql, LockOptions aliasedLockOptions, Map keyColumnNames) {
return sql + new ForUpdateFragment( this, aliasedLockOptions, keyColumnNames ).toFragmentString();
}
@Override
public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() {
return new SQLExceptionConversionDelegate() {
@Override
public JDBCException convert(SQLException sqlException, String message, String sql) {
final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException );
if("JZ0TO".equals( sqlState ) || "JZ006".equals( sqlState )){
throw new LockTimeoutException( message, sqlException, sql );
}
return null;
}
};
}
}

View File

@ -434,4 +434,9 @@ public class SybaseASE15Dialect extends AbstractTransactSQLDialect {
protected SqlTypeDescriptor getSqlTypeDescriptorOverride(int sqlCode) {
return sqlCode == Types.BOOLEAN ? TinyIntTypeDescriptor.INSTANCE : super.getSqlTypeDescriptorOverride( sqlCode );
}
@Override
public boolean supportsLockTimeouts() {
return false;
}
}