From 390f390b29bc859baca0ba4be551428d7f3c83fc Mon Sep 17 00:00:00 2001 From: Jeremy Bauer Date: Tue, 17 Mar 2009 04:39:56 +0000 Subject: [PATCH] OPENJPA-878 Committing code, tests, and documentation updates for Donald Woods. git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@755113 13f79535-47bb-0310-9956-ffa450edef68 --- .../openjpa/jdbc/kernel/FinderQueryImpl.java | 2 +- .../openjpa/jdbc/kernel/JDBCStoreQuery.java | 2 + .../openjpa/jdbc/kernel/NativeJDBCSeq.java | 2 + .../jdbc/kernel/PessimisticLockManager.java | 22 +----- .../jdbc/kernel/PreparedSQLStoreQuery.java | 3 + .../openjpa/jdbc/kernel/SQLStoreQuery.java | 4 + .../openjpa/jdbc/kernel/TableJDBCSeq.java | 6 +- .../ClassNameDiscriminatorStrategy.java | 7 +- .../strats/MaxEmbeddedLobFieldStrategy.java | 6 +- .../jdbc/schema/TableSchemaFactory.java | 5 +- .../openjpa/jdbc/sql/DB2Dictionary.java | 4 + .../apache/openjpa/jdbc/sql/DBDictionary.java | 79 ++++++++++++++++++- .../openjpa/jdbc/sql/DerbyDictionary.java | 2 +- .../openjpa/jdbc/sql/OracleDictionary.java | 6 +- .../openjpa/jdbc/sql/PostgresDictionary.java | 13 ++- .../openjpa/jdbc/sql/SQLErrorCodeReader.java | 2 +- .../openjpa/jdbc/sql/SQLExceptions.java | 3 + .../apache/openjpa/jdbc/sql/SelectImpl.java | 24 +----- .../jdbc/sql/sql-error-state-codes.xml | 20 ++++- 19 files changed, 155 insertions(+), 57 deletions(-) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderQueryImpl.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderQueryImpl.java index dfeb01ece..07458a905 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderQueryImpl.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/FinderQueryImpl.java @@ -149,7 +149,7 @@ public class FinderQueryImpl dict.setUnknown(stmnt, i+1, params[i], _pkCols[i]); } } - + dict.setTimeouts(stmnt, (JDBCFetchConfiguration)fetch, forUpdate); rs = _select.executeQuery(conn, stmnt, getQueryString(), jstore, params, _pkCols); return _select.getEagerResult(conn, stmnt, rs, jstore, diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java index 868382b83..d70ea1f8b 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import org.apache.openjpa.event.LifecycleEventManager; +import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.kernel.exps.ExpContext; import org.apache.openjpa.jdbc.kernel.exps.GetColumn; import org.apache.openjpa.jdbc.kernel.exps.JDBCExpressionFactory; @@ -512,6 +513,7 @@ public class JDBCStoreQuery stmnt = null; try { stmnt = prepareStatement(conn, sql[i]); + dict.setTimeouts(stmnt, fetch, true); count += executeUpdate(conn, stmnt, sql[i], isUpdate); } catch (SQLException se) { throw SQLExceptions.getStore(se, sql[i].getSQL(), diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java index 348e2d621..ac0e62aed 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/NativeJDBCSeq.java @@ -290,10 +290,12 @@ public class NativeJDBCSeq */ private long getSequence(Connection conn) throws SQLException { + DBDictionary dict = _conf.getDBDictionaryInstance(); PreparedStatement stmnt = null; ResultSet rs = null; try { stmnt = conn.prepareStatement(_select); + dict.setTimeouts(stmnt, _conf, false); synchronized(this) { rs = stmnt.executeQuery(); } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java index fccdd76cf..5284e6b29 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PessimisticLockManager.java @@ -111,6 +111,7 @@ public class PessimisticLockManager // construct; if not, and we the assertion does not throw an // exception, then just return without locking DBDictionary dict = _store.getDBDictionary(); + JDBCFetchConfiguration fetch = _store.getFetchConfiguration(); if (dict.simulateLocking) return; dict.assertSupport(dict.supportsSelectForUpdate, @@ -125,7 +126,7 @@ public class PessimisticLockManager Select select = _store.getSQLFactory().newSelect(); select.select(mapping.getPrimaryKeyColumns()); select.wherePrimaryKey(id, mapping, _store); - SQLBuffer sql = select.toSelect(true, _store.getFetchConfiguration()); + SQLBuffer sql = select.toSelect(true, fetch); ensureStoreManagerTransaction(); Connection conn = _store.getConnection(); @@ -133,7 +134,7 @@ public class PessimisticLockManager ResultSet rs = null; try { stmnt = prepareStatement(conn, sql); - setTimeout(stmnt, timeout); + dict.setTimeouts(stmnt, fetch, true); rs = executeQuery(conn, stmnt, sql); checkLock(rs, sm, timeout); } catch (SQLException se) { @@ -175,23 +176,6 @@ public class PessimisticLockManager return sql.prepareStatement(conn); } - /** - * This method is to provide override for non-JDBC or JDBC-like - * implementation of setting query timeout. - */ - protected void setTimeout(PreparedStatement stmnt, int timeout) - throws SQLException { - DBDictionary dict = _store.getDBDictionary(); - if (timeout >= 0 && dict.supportsQueryTimeout) { - if (timeout < 1000) { - timeout = 1000; - if (log.isWarnEnabled()) - log.warn(_loc.get("millis-query-timeout")); - } - stmnt.setQueryTimeout(timeout / 1000); - } - } - /** * This method is to provide override for non-JDBC or JDBC-like * implementation of executing query. diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java index a070b9ccb..cb66a7685 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/PreparedSQLStoreQuery.java @@ -24,6 +24,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Map; +import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.sql.DBDictionary; import org.apache.openjpa.jdbc.sql.Result; @@ -101,6 +102,8 @@ public class PreparedSQLStoreQuery extends SQLStoreQuery { for (int i = 0; i < params.length; i++) dict.setUnknown(stmnt, ++index, params[i], null); + dict.setTimeouts(stmnt, fetch, false); + ResultSet rs = stmnt.executeQuery(); SelectImpl cachedSelect = pq.getSelect(); diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java index 8a4557458..1bf44ee9a 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java @@ -34,6 +34,7 @@ import java.util.Map; import java.util.Set; import org.apache.commons.lang.StringUtils; +import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.meta.MappingRepository; import org.apache.openjpa.jdbc.meta.QueryResultMapping; @@ -166,6 +167,8 @@ public class SQLStoreQuery if (stmnt != null) buf.setParameters(stmnt); + dict.setTimeouts(stmnt, fetch, true); + int count = executeUpdate(store, conn, stmnt, buf); return Numbers.valueOf(count); @@ -218,6 +221,7 @@ public class SQLStoreQuery stmnt != null;) dict.setUnknown(stmnt, ++index, i.next(), null); + dict.setTimeouts(stmnt, fetch, false); ResultSet rs = executeQuery(store, conn, stmnt, buf, paramList); ResultSetResult res = stmnt != null ? new ResultSetResult(conn, stmnt, rs, store) : diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java index 7532cdf23..7bb6cbc7c 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/TableJDBCSeq.java @@ -467,6 +467,7 @@ public class TableJDBCSeq PreparedStatement stmnt = null; try { stmnt = prepareStatement(conn, insert); + dict.setTimeouts(stmnt, _conf, true); executeUpdate(_conf, conn, stmnt, insert, RowImpl.ACTION_INSERT); } finally { if (stmnt != null) @@ -508,9 +509,11 @@ public class TableJDBCSeq null, false, dict.supportsSelectForUpdate, 0, Long.MAX_VALUE, false, true); - PreparedStatement stmnt = prepareStatement(conn, select); + PreparedStatement stmnt = null; ResultSet rs = null; try { + stmnt = prepareStatement(conn, select); + dict.setTimeouts(stmnt, _conf, false); rs = executeQuery(_conf, conn, stmnt, select); return getSequence(rs, dict); } finally { @@ -566,6 +569,7 @@ public class TableJDBCSeq appendValue(Numbers.valueOf(cur), _seqColumn); stmnt = prepareStatement(conn, upd); + dict.setTimeouts(stmnt, _conf, true); updates = executeUpdate(_conf, conn, stmnt, upd, RowImpl.ACTION_UPDATE); } finally { if (rs != null) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java index 2b9cac702..2c81abe64 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/ClassNameDiscriminatorStrategy.java @@ -24,6 +24,8 @@ import java.sql.ResultSet; import java.sql.SQLException; import org.apache.commons.lang.StringUtils; +import org.apache.openjpa.jdbc.conf.JDBCConfiguration; +import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.schema.Column; @@ -73,9 +75,9 @@ public class ClassNameDiscriminatorStrategy Column col = disc.getColumns()[0]; DBDictionary dict = store.getDBDictionary(); + JDBCFetchConfiguration fetch = store.getFetchConfiguration(); SQLBuffer select = dict.toSelect(new SQLBuffer(dict).append(col), - store.getFetchConfiguration(), - new SQLBuffer(dict).append(col.getTable()), null, null, + fetch, new SQLBuffer(dict).append(col.getTable()), null, null, null, null, true, false, 0, Long.MAX_VALUE); Log log = disc.getMappingRepository().getLog(); @@ -88,6 +90,7 @@ public class ClassNameDiscriminatorStrategy ResultSet rs = null; try { stmnt = select.prepareStatement(conn); + dict.setTimeouts(stmnt, fetch, false); rs = stmnt.executeQuery(); String className; while (rs.next()) { diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedLobFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedLobFieldStrategy.java index e5cf3a6b3..8618647d7 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedLobFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/MaxEmbeddedLobFieldStrategy.java @@ -23,6 +23,7 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; +import org.apache.openjpa.jdbc.conf.JDBCConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.meta.JavaSQLTypes; @@ -142,20 +143,23 @@ abstract class MaxEmbeddedLobFieldStrategy public void customUpdate(OpenJPAStateManager sm, JDBCStore store) throws SQLException { + JDBCFetchConfiguration fetch = store.getFetchConfiguration(); // select existing value for update Column col = field.getColumns()[0]; Select sel = store.getSQLFactory().newSelect(); sel.select(col); field.wherePrimaryKey(sel, sm, store); - SQLBuffer sql = sel.toSelect(true, store.getFetchConfiguration()); + SQLBuffer sql = sel.toSelect(true, fetch); Connection conn = store.getConnection(); + DBDictionary dict = store.getDBDictionary(); PreparedStatement stmnt = null; ResultSet rs = null; try { stmnt = sql.prepareStatement(conn, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); + dict.setTimeouts(stmnt, fetch, true); rs = stmnt.executeQuery(); rs.next(); diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/TableSchemaFactory.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/TableSchemaFactory.java index df21bcf4b..0d444cf3b 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/TableSchemaFactory.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/schema/TableSchemaFactory.java @@ -235,7 +235,7 @@ public class TableSchemaFactory + " (" + _pkColumn + ", " + _schemaColumn + ") VALUES (?, ?)"); dict.setInt(stmnt, 1, 1, _pkColumn); dict.setNull(stmnt, 2, _schemaColumn.getType(), _schemaColumn); - + dict.setTimeouts(stmnt, _conf, true); stmnt.executeUpdate(); } finally { if (stmnt != null) @@ -290,6 +290,7 @@ public class TableSchemaFactory conn.setAutoCommit(true); stmnt = select.prepareStatement(conn); + dict.setQueryTimeout(stmnt, _conf.getQueryTimeout()); rs = stmnt.executeQuery(); rs.next(); String schema = (_schemaColumn.getType() == Types.CLOB) ? @@ -353,12 +354,14 @@ public class TableSchemaFactory else dict.setString(stmnt, 1, schema, _schemaColumn); dict.setInt(stmnt, 2, 1, _pkColumn); + dict.setTimeouts(stmnt, _conf, true); stmnt.executeUpdate(); } else { stmnt = conn.prepareStatement(update, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); dict.setInt(stmnt, 1, 1, _pkColumn); + dict.setTimeouts(stmnt, _conf, true); rs = stmnt.executeQuery(); rs.next(); dict.putString(rs.getClob(1), schema); diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java index 059943d00..7bff42112 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java @@ -843,6 +843,10 @@ public class DB2Dictionary if (subtype == StoreException.LOCK && errorState.equals("57033") && ex.getMessage().indexOf("80") != -1) { recoverable = Boolean.TRUE; + } else if (subtype == StoreException.QUERY && errorState.equals("57014") + && ex.getMessage().indexOf("40001") == -1) { + // FIXME drwoods - OPENJPA-964 - Need to determine expected DB2 behavior for query timeouts + recoverable = Boolean.TRUE; } } return recoverable; diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java index 033b07078..acf9c65ff 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java @@ -109,6 +109,7 @@ import org.apache.openjpa.util.ObjectExistsException; import org.apache.openjpa.util.ObjectNotFoundException; import org.apache.openjpa.util.OpenJPAException; import org.apache.openjpa.util.OptimisticException; +import org.apache.openjpa.util.QueryException; import org.apache.openjpa.util.ReferentialIntegrityException; import org.apache.openjpa.util.Serialization; import org.apache.openjpa.util.StoreException; @@ -3649,7 +3650,7 @@ public class DBDictionary stmnt.setString(idx++, schemaName.toUpperCase()); if (sequenceName != null) stmnt.setString(idx++, sequenceName); - + setQueryTimeout(stmnt, conf.getQueryTimeout()); rs = executeQuery(conn, stmnt, str); return getSequence(rs); } finally { @@ -4046,6 +4047,7 @@ public class DBDictionary PreparedStatement stmnt = prepareStatement(conn, query); ResultSet rs = null; try { + setQueryTimeout(stmnt, conf.getQueryTimeout()); rs = executeQuery(conn, stmnt, query); return getKey(rs, col); } finally { @@ -4174,6 +4176,76 @@ public class DBDictionary } } + /** + * FIXME - OPENJPA-957 - lockTimeout is a server-side function and + * shouldn't be using client-side setQueryTimeout for lock timeouts. + * + * This method is to provide override for non-JDBC or JDBC-like + * implementation of setting query and lock timeouts. + * + * @param stmnt + * @param fetch + * @param forUpdate - true if we should also try setting a lock timeout + * @throws SQLException + */ + public void setTimeouts(PreparedStatement stmnt, + JDBCFetchConfiguration fetch, boolean forUpdate) throws SQLException { + if (this.supportsQueryTimeout) { + int timeout = fetch.getQueryTimeout(); + if (forUpdate) { + // if this is a locking select and the lock timeout is greater + // than the configured query timeout, use the lock timeout + timeout = Math.max(fetch.getQueryTimeout(), + fetch.getLockTimeout()); + } + setQueryTimeout(stmnt, timeout); + } + } + + /** + * FIXME - OPENJPA-957 - lockTimeout is a server-side function and + * shouldn't be using client-side setQueryTimeout for lock timeouts. + * + * This method is to provide override for non-JDBC or JDBC-like + * implementation of setting query and lock timeouts. + * + * @param stmnt + * @param fetch + * @param forUpdate - true if we should also try setting a lock timeout + * @throws SQLException + */ + public void setTimeouts(PreparedStatement stmnt, JDBCConfiguration conf, + boolean forUpdate) throws SQLException { + if (this.supportsQueryTimeout) { + int timeout = conf.getQueryTimeout(); + if (forUpdate) { + // if this is a locking select and the lock timeout is greater + // than the configured query timeout, use the lock timeout + timeout = Math.max(conf.getQueryTimeout(), + conf.getLockTimeout()); + } + setQueryTimeout(stmnt, timeout); + } + } + + /** + * This method is to provide override for non-JDBC or JDBC-like + * implementation of setting query timeout. + */ + public void setQueryTimeout(PreparedStatement stmnt, int timeout) + throws SQLException { + if (this.supportsQueryTimeout && timeout >= 0) { + if (timeout > 0 && timeout < 1000) { + timeout = 1000; + Log log = conf.getLog(JDBCConfiguration.LOG_JDBC); + if (log.isWarnEnabled()) + log.warn(_loc.get("millis-query-timeout")); + } + stmnt.setQueryTimeout(timeout / 1000); + } + } + + ////////////////////////////////////// // ConnectionDecorator implementation ////////////////////////////////////// @@ -4276,6 +4348,9 @@ public class DBDictionary case StoreException.REFERENTIAL_INTEGRITY: storeEx = new ReferentialIntegrityException(msg); break; + case StoreException.QUERY: + storeEx = new QueryException(msg); + break; default: storeEx = new StoreException(msg); } @@ -4362,6 +4437,7 @@ public class DBDictionary stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); + setTimeouts(stmnt, store.getFetchConfiguration(), true); res = stmnt.executeQuery(); if (!res.next()) { throw new InternalException(_loc.get("stream-exception")); @@ -4395,6 +4471,7 @@ public class DBDictionary stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(), ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); + setTimeouts(stmnt, store.getFetchConfiguration(), true); res = stmnt.executeQuery(); if (!res.next()) { throw new InternalException(_loc.get("stream-exception")); diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java index 761a58a21..340e8a69f 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DerbyDictionary.java @@ -113,7 +113,7 @@ public class DerbyDictionary int errorCode = ex.getErrorCode(); if (errorStates.contains(errorState)) { recoverable = Boolean.FALSE; - if (subtype == StoreException.LOCK && errorCode < 30000) { + if ((subtype == StoreException.LOCK || subtype == StoreException.QUERY) && errorCode < 30000) { recoverable = Boolean.TRUE; } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java index 2714a8448..08881417f 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/OracleDictionary.java @@ -655,7 +655,7 @@ public class OracleDictionary setString(stmnt, idx++, schemaName.toUpperCase(), null); if (tableName != null) setString(stmnt, idx++, tableName.toUpperCase(), null); - + setTimeouts(stmnt, conf, false); rs = stmnt.executeQuery(); List pkList = new ArrayList(); while (rs != null && rs.next()) @@ -703,6 +703,7 @@ public class OracleDictionary if (tableName != null) setString(stmnt, idx++, tableName.toUpperCase(), null); + setTimeouts(stmnt, conf, false); rs = stmnt.executeQuery(); List idxList = new ArrayList(); while (rs != null && rs.next()) @@ -769,7 +770,7 @@ public class OracleDictionary setString(stmnt, idx++, schemaName.toUpperCase(), null); if (tableName != null) setString(stmnt, idx++, tableName.toUpperCase(), null); - + setTimeouts(stmnt, conf, false); rs = stmnt.executeQuery(); List fkList = new ArrayList(); while (rs != null && rs.next()) @@ -888,6 +889,7 @@ public class OracleDictionary + ".currval FROM DUAL"); ResultSet rs = null; try { + setTimeouts(stmnt, conf, false); rs = stmnt.executeQuery(); rs.next(); return Numbers.valueOf(rs.getLong(1)); diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java index 9feec19eb..de5db021a 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/PostgresDictionary.java @@ -32,6 +32,7 @@ import java.text.SimpleDateFormat; import java.util.Arrays; import java.util.Date; +import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.kernel.exps.FilterValue; import org.apache.openjpa.jdbc.schema.Column; @@ -382,14 +383,16 @@ public class PostgresDictionary private void updatePostgresBlob(Row row, Column col, JDBCStore store, Object ob, Select sel) throws SQLException { - SQLBuffer sql = sel.toSelect(true, store.getFetchConfiguration()); + JDBCFetchConfiguration fetch = store.getFetchConfiguration(); + SQLBuffer sql = sel.toSelect(true, fetch); ResultSet res = null; DelegatingConnection conn = (DelegatingConnection) store.getConnection(); PreparedStatement stmnt = null; try { - stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(), + stmnt = sql.prepareStatement(conn, fetch, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); + setTimeouts(stmnt, fetch, true); res = stmnt.executeQuery(); if (!res.next()) { throw new InternalException(_loc.get("stream-exception")); @@ -443,14 +446,16 @@ public class PostgresDictionary } public void deleteStream(JDBCStore store, Select sel) throws SQLException { - SQLBuffer sql = sel.toSelect(true, store.getFetchConfiguration()); + JDBCFetchConfiguration fetch = store.getFetchConfiguration(); + SQLBuffer sql = sel.toSelect(true, fetch); ResultSet res = null; DelegatingConnection conn = (DelegatingConnection) store.getConnection(); PreparedStatement stmnt = null; try { - stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(), + stmnt = sql.prepareStatement(conn, fetch, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); + setTimeouts(stmnt, fetch, true); res = stmnt.executeQuery(); if (!res.next()) { throw new InternalException(_loc.get("stream-exception")); diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLErrorCodeReader.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLErrorCodeReader.java index 5ed844a4b..ef6c174d2 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLErrorCodeReader.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLErrorCodeReader.java @@ -60,7 +60,7 @@ public class SQLErrorCodeReader { storeErrorTypes.put("optimistic", StoreException.OPTIMISTIC); storeErrorTypes.put("referential-integrity", StoreException.REFERENTIAL_INTEGRITY); - + storeErrorTypes.put("query", StoreException.QUERY); } private static final Localizer _loc = diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java index 289bbe6b5..2afef52c6 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLExceptions.java @@ -28,6 +28,7 @@ import org.apache.openjpa.kernel.OpenJPAStateManager; import org.apache.openjpa.lib.util.Localizer.Message; import org.apache.openjpa.util.LockException; import org.apache.openjpa.util.OpenJPAException; +import org.apache.openjpa.util.QueryException; import org.apache.openjpa.util.StoreException; /** @@ -130,6 +131,8 @@ public class SQLExceptions { if (storeEx.getSubtype() == StoreException.LOCK) { LockException lockEx = (LockException) storeEx; lockEx.setLockLevel(level); + } else if (storeEx.getSubtype() == StoreException.QUERY) { + QueryException QueryEx = (QueryException) storeEx; } return storeEx; } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java index 779b92b9f..2dc3b4b1f 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java @@ -322,6 +322,7 @@ public class SelectImpl stmnt = prepareStatement(conn, sql, null, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, false); + _dict.setQueryTimeout(stmnt, store.getFetchConfiguration().getQueryTimeout()); rs = executeQuery(conn, stmnt, sql, false, store); return getCount(rs); } finally { @@ -377,7 +378,7 @@ public class SelectImpl else stmnt = prepareStatement(conn, sql, null, rsType, -1, false); - setTimeout(stmnt, forUpdate, fetch); + _dict.setTimeouts(stmnt, fetch, forUpdate); rs = executeQuery(conn, stmnt, sql, isLRS, store); } catch (SQLException se) { @@ -448,27 +449,6 @@ public class SelectImpl return conn.prepareStatement(sql); } - /** - * This method is to provide override for non-JDBC or JDBC-like - * implementation of setting query timeout. - */ - protected void setTimeout(PreparedStatement stmnt, boolean forUpdate, - JDBCFetchConfiguration fetch) throws SQLException { - // if this is a locking select and the lock timeout is greater than - // the configured query timeout, use the lock timeout - if (forUpdate && _dict.supportsQueryTimeout && fetch != null - && fetch.getLockTimeout() > stmnt.getQueryTimeout() * 1000) { - int timeout = fetch.getLockTimeout(); - if (timeout < 1000) { - timeout = 1000; - Log log = _conf.getLog(JDBCConfiguration.LOG_JDBC); - if (log.isWarnEnabled()) - log.warn(_loc.get("millis-query-timeout")); - } - stmnt.setQueryTimeout(timeout / 1000); - } - } - /** * This method is to provide override for non-JDBC or JDBC-like * implementation of executing query. diff --git a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml index d9af606d0..f889a3315 100644 --- a/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml +++ b/openjpa-jdbc/src/main/resources/org/apache/openjpa/jdbc/sql/sql-error-state-codes.xml @@ -29,11 +29,12 @@ - 40001,57033,57014 + 40001,57033 23502,42912,23001,23504,23511,23512,23513,23515,23520,23505 + 57014 @@ -42,6 +43,7 @@ 23505 + XCL52 @@ -50,6 +52,7 @@ 1205 + @@ -58,6 +61,7 @@ 1205 + @@ -66,6 +70,7 @@ 23505,456c 40XL1,40001 + @@ -74,6 +79,7 @@ 23505,456c 40XL1,40001 + @@ -82,6 +88,7 @@ 23505,456c 40XL1,40001 + @@ -90,6 +97,7 @@ 23505,456c 40XL1,40001 + @@ -98,6 +106,7 @@ + @@ -106,6 +115,7 @@ + @@ -114,6 +124,7 @@ + @@ -122,6 +133,7 @@ + @@ -130,6 +142,7 @@ + @@ -138,6 +151,7 @@ + @@ -146,6 +160,7 @@ 23000 41000,1205,1213 + @@ -154,6 +169,7 @@ + @@ -162,6 +178,7 @@ + @@ -170,6 +187,7 @@ 55P03 + \ No newline at end of file