Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 36 additions & 5 deletions hibernate-core/src/main/java/org/hibernate/dialect/H2Dialect.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,25 @@
*/
package org.hibernate.dialect;

import java.sql.SQLException;
import java.sql.Types;

import org.jboss.logging.Logger;

import org.hibernate.JDBCException;
import org.hibernate.PessimisticLockException;
import org.hibernate.cfg.AvailableSettings;
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.LockAcquisitionException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.JdbcExceptionHelper;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.type.StandardBasicTypes;
import org.jboss.logging.Logger;

import java.sql.SQLException;
import java.sql.Types;

/**
* A dialect compatible with the H2 database.
Expand Down Expand Up @@ -292,6 +296,33 @@ public String extractConstraintName(SQLException sqle) {
return constraintName;
}
};

@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;

int errorCode = JdbcExceptionHelper.extractErrorCode(sqlException);

if (40001 == errorCode) { // DEADLOCK DETECTED
exception = new LockAcquisitionException(message, sqlException, sql);
}

if (50200 == errorCode) { // LOCK NOT AVAILABLE
exception = new PessimisticLockException(message, sqlException, sql);
}

return exception;
}
};
}
return delegate;
}

@Override
public boolean supportsTemporaryTables() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,17 @@
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.JDBCException;
import org.hibernate.LockOptions;
import org.hibernate.PessimisticLockException;
import org.hibernate.cfg.Environment;
import org.hibernate.dialect.function.NoArgSQLFunction;
import org.hibernate.dialect.function.PositionSubstringFunction;
import org.hibernate.dialect.function.SQLFunctionTemplate;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.dialect.function.VarArgsSQLFunction;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;
import org.hibernate.exception.spi.TemplatedViolatedConstraintNameExtracter;
import org.hibernate.exception.spi.ViolatedConstraintNameExtracter;
import org.hibernate.id.SequenceGenerator;
Expand Down Expand Up @@ -367,6 +371,34 @@ public String extractConstraintName(SQLException sqle) {
}
};

@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 delegate;
}

public int registerResultSetOutParameter(CallableStatement statement, int col) throws SQLException {
// Register the type of the out param - PostgreSQL uses Types.OTHER
statement.registerOutParameter(col++, Types.OTHER);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
* third-party contributors as indicated by either @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.dialect;

import org.junit.Test;

import java.sql.SQLException;
import org.hibernate.JDBCException;
import org.hibernate.PessimisticLockException;
import org.hibernate.exception.LockAcquisitionException;
import org.hibernate.exception.spi.SQLExceptionConversionDelegate;

import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;

import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;


/**
* Testing of patched support for PostgreSQL Lock error detection. HHH-7251
*
* @author Bryan Varner
*/
@TestForIssue( jiraKey = "HHH-7251" )
public class PostgreSQL81DialectTestCase extends BaseUnitTestCase {

@Test
public void testDeadlockException() {
PostgreSQL81Dialect dialect = new PostgreSQL81Dialect();
SQLExceptionConversionDelegate delegate = dialect.buildSQLExceptionConversionDelegate();
assertNotNull(delegate);

JDBCException exception = delegate.convert(new SQLException("Deadlock Detected", "40P01"), "", "");
assertTrue(exception instanceof LockAcquisitionException);
}

@Test
public void testTimeoutException() {
PostgreSQL81Dialect dialect = new PostgreSQL81Dialect();
SQLExceptionConversionDelegate delegate = dialect.buildSQLExceptionConversionDelegate();
assertNotNull(delegate);

JDBCException exception = delegate.convert(new SQLException("Lock Not Available", "55P03"), "", "");
assertTrue(exception instanceof PessimisticLockException);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -792,9 +792,10 @@ public <A> A find(Class<A> entityClass, Object primaryKey, LockModeType lockMode
try {
getSession().setCacheMode( cacheMode );
if ( lockModeType != null ) {
lockOptions = getLockRequest( lockModeType, properties );
return ( A ) getSession().get(
entityClass, ( Serializable ) primaryKey,
getLockRequest( lockModeType, properties )
entityClass, ( Serializable ) primaryKey,
lockOptions
);
}
else {
Expand Down Expand Up @@ -919,7 +920,8 @@ public void refresh(Object entity, LockModeType lockModeType, Map<String, Object
throw new IllegalArgumentException( "Entity not managed" );
}
if ( lockModeType != null ) {
getSession().refresh( entity, ( lockOptions = getLockRequest( lockModeType, properties ) ) );
lockOptions = getLockRequest( lockModeType, properties );
getSession().refresh( entity, lockOptions );
}
else {
getSession().refresh( entity );
Expand Down Expand Up @@ -1096,8 +1098,8 @@ public void lock(Object entity, LockModeType lockModeType, Map<String, Object> p
if ( !contains( entity ) ) {
throw new IllegalArgumentException( "entity not in the persistence context" );
}
getSession().buildLockRequest( ( lockOptions = getLockRequest( lockModeType, properties ) ) )
.lock( entity );
lockOptions = getLockRequest( lockModeType, properties );
getSession().buildLockRequest( lockOptions ).lock( entity );
}
catch ( HibernateException he ) {
throw convert( he, lockOptions );
Expand Down
Loading