@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 ( "HY008".equals( sqlState ) ) { throw new QueryTimeoutException( message, sqlException, sql ); } if (1222 == errorCode ) { throw new LockTimeoutException( message, sqlException, sql ); } return null; } }; }
@Override public JDBCException convert(SQLException sqlException, String message, String sql) { if ( SQLClientInfoException.class.isInstance( sqlException ) || SQLInvalidAuthorizationSpecException.class.isInstance( sqlException ) || SQLNonTransientConnectionException.class.isInstance( sqlException ) || SQLTransientConnectionException.class.isInstance( sqlException ) ) { return new JDBCConnectionException( message, sqlException, sql ); } else if ( DataTruncation.class.isInstance( sqlException ) || SQLDataException.class.isInstance( sqlException ) ) { throw new DataException( message, sqlException, sql ); } else if ( SQLIntegrityConstraintViolationException.class.isInstance( sqlException ) ) { return new ConstraintViolationException( message, sqlException, sql, getConversionContext().getViolatedConstraintNameExtracter().extractConstraintName( sqlException ) ); } else if ( SQLSyntaxErrorException.class.isInstance( sqlException ) ) { return new SQLGrammarException( message, sqlException, sql ); } else if ( SQLTimeoutException.class.isInstance( sqlException ) ) { return new QueryTimeoutException( message, sqlException, sql ); } else if ( SQLTransactionRollbackException.class.isInstance( sqlException ) ) { // Not 100% sure this is completely accurate. The JavaDocs for SQLTransactionRollbackException state that // it indicates sql states starting with '40' and that those usually indicate that: // <quote> // the current statement was automatically rolled back by the database because of deadlock or // other transaction serialization failures. // </quote> return new LockAcquisitionException( message, sqlException, sql ); } return null; // allow other delegates the chance to look }
private boolean isDatabaseProblem(Throwable e) { if(e instanceof PersistenceException) { return e instanceof javax.persistence.QueryTimeoutException || isDatabaseProblem(e.getCause()); } return e instanceof QueryTimeoutException || e instanceof JDBCConnectionException; }
@Override public JDBCException convert(SQLException sqlException, String message, String sql) { final String sqlState = JdbcExceptionHelper.extractSqlState( sqlException ); final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException ); if ( sqlState != null ) { String sqlStateClassCode = JdbcExceptionHelper.determineSqlStateClassCode( sqlState ); if ( sqlStateClassCode != null ) { if ( SQL_GRAMMAR_CATEGORIES.contains( sqlStateClassCode ) ) { return new SQLGrammarException( message, sqlException, sql ); } else if ( INTEGRITY_VIOLATION_CATEGORIES.contains( sqlStateClassCode ) ) { final String constraintName = getConversionContext() .getViolatedConstraintNameExtracter() .extractConstraintName( sqlException ); return new ConstraintViolationException( message, sqlException, sql, constraintName ); } else if ( CONNECTION_CATEGORIES.contains( sqlStateClassCode ) ) { return new JDBCConnectionException( message, sqlException, sql ); } else if ( DATA_CATEGORIES.contains( sqlStateClassCode ) ) { return new DataException( message, sqlException, sql ); } } if ( "40001".equals( sqlState ) ) { return new LockAcquisitionException( message, sqlException, sql ); } if ( "40XL1".equals( sqlState ) || "40XL2".equals( sqlState )) { // Derby "A lock could not be obtained within the time requested." return new PessimisticLockException( message, sqlException, sql ); } // MySQL Query execution was interrupted if ( "70100".equals( sqlState ) || // Oracle user requested cancel of current operation ( "72000".equals( sqlState ) && errorCode == 1013 ) ) { throw new QueryTimeoutException( message, sqlException, sql ); } } return null; }
@Override public SQLExceptionConversionDelegate buildSQLExceptionConversionDelegate() { return new SQLExceptionConversionDelegate() { @Override public JDBCException convert(SQLException sqlException, String message, String sql) { // interpreting Oracle exceptions is much much more precise based on their specific vendor codes. final int errorCode = JdbcExceptionHelper.extractErrorCode( sqlException ); // lock timeouts ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ( errorCode == 30006 ) { // ORA-30006: resource busy; acquire with WAIT timeout expired throw new LockTimeoutException( message, sqlException, sql ); } else if ( errorCode == 54 ) { // ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired throw new LockTimeoutException( message, sqlException, sql ); } else if ( 4021 == errorCode ) { // ORA-04021 timeout occurred while waiting to lock object throw new LockTimeoutException( message, sqlException, sql ); } // deadlocks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ( 60 == errorCode ) { // ORA-00060: deadlock detected while waiting for resource return new LockAcquisitionException( message, sqlException, sql ); } else if ( 4020 == errorCode ) { // ORA-04020 deadlock detected while trying to lock object return new LockAcquisitionException( message, sqlException, sql ); } // query cancelled ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if ( 1013 == errorCode ) { // ORA-01013: user requested cancel of current operation throw new QueryTimeoutException( message, sqlException, sql ); } // 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; } }; }
@Override public void doExecute(ProcessBundle bundle) throws Exception { OBError msg = new OBError(); msg.setType("Success"); msg.setTitle(OBMessageUtils.messageBD("Success")); try { // retrieve standard params String strProductId = (String) bundle.getParams().get("mProductId"); String strChValueId = (String) bundle.getParams().get("mChValueId"); update(strProductId, strChValueId); bundle.setResult(msg); // Postgres wraps the exception into a GenericJDBCException } catch (GenericJDBCException ge) { log4j.error("Exception processing variant generation", ge); msg.setType("Error"); msg.setTitle(OBMessageUtils.messageBD(bundle.getConnection(), "Error", bundle.getContext() .getLanguage())); msg.setMessage(ge.getSQLException().getMessage()); bundle.setResult(msg); OBDal.getInstance().rollbackAndClose(); // Oracle wraps the exception into a QueryTimeoutException } catch (QueryTimeoutException qte) { log4j.error("Exception processing variant generation", qte); msg.setType("Error"); msg.setTitle(OBMessageUtils.messageBD(bundle.getConnection(), "Error", bundle.getContext() .getLanguage())); msg.setMessage(qte.getSQLException().getMessage().split("\n")[0]); bundle.setResult(msg); OBDal.getInstance().rollbackAndClose(); } catch (final Exception e) { log4j.error("Exception processing variant generation", e); msg.setType("Error"); msg.setTitle(OBMessageUtils.messageBD(bundle.getConnection(), "Error", bundle.getContext() .getLanguage())); msg.setMessage(FIN_Utility.getExceptionMessage(e)); bundle.setResult(msg); OBDal.getInstance().rollbackAndClose(); } }