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
This commit is contained in:
Jeremy Bauer 2009-03-17 04:39:56 +00:00
parent 7c9ef84fb9
commit 390f390b29
19 changed files with 155 additions and 57 deletions

View File

@ -149,7 +149,7 @@ public class FinderQueryImpl
dict.setUnknown(stmnt, i+1, params[i], _pkCols[i]); dict.setUnknown(stmnt, i+1, params[i], _pkCols[i]);
} }
} }
dict.setTimeouts(stmnt, (JDBCFetchConfiguration)fetch, forUpdate);
rs = _select.executeQuery(conn, stmnt, getQueryString(), jstore, rs = _select.executeQuery(conn, stmnt, getQueryString(), jstore,
params, _pkCols); params, _pkCols);
return _select.getEagerResult(conn, stmnt, rs, jstore, return _select.getEagerResult(conn, stmnt, rs, jstore,

View File

@ -30,6 +30,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.openjpa.event.LifecycleEventManager; 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.ExpContext;
import org.apache.openjpa.jdbc.kernel.exps.GetColumn; import org.apache.openjpa.jdbc.kernel.exps.GetColumn;
import org.apache.openjpa.jdbc.kernel.exps.JDBCExpressionFactory; import org.apache.openjpa.jdbc.kernel.exps.JDBCExpressionFactory;
@ -512,6 +513,7 @@ public class JDBCStoreQuery
stmnt = null; stmnt = null;
try { try {
stmnt = prepareStatement(conn, sql[i]); stmnt = prepareStatement(conn, sql[i]);
dict.setTimeouts(stmnt, fetch, true);
count += executeUpdate(conn, stmnt, sql[i], isUpdate); count += executeUpdate(conn, stmnt, sql[i], isUpdate);
} catch (SQLException se) { } catch (SQLException se) {
throw SQLExceptions.getStore(se, sql[i].getSQL(), throw SQLExceptions.getStore(se, sql[i].getSQL(),

View File

@ -290,10 +290,12 @@ public class NativeJDBCSeq
*/ */
private long getSequence(Connection conn) private long getSequence(Connection conn)
throws SQLException { throws SQLException {
DBDictionary dict = _conf.getDBDictionaryInstance();
PreparedStatement stmnt = null; PreparedStatement stmnt = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
stmnt = conn.prepareStatement(_select); stmnt = conn.prepareStatement(_select);
dict.setTimeouts(stmnt, _conf, false);
synchronized(this) { synchronized(this) {
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
} }

View File

@ -111,6 +111,7 @@ public class PessimisticLockManager
// construct; if not, and we the assertion does not throw an // construct; if not, and we the assertion does not throw an
// exception, then just return without locking // exception, then just return without locking
DBDictionary dict = _store.getDBDictionary(); DBDictionary dict = _store.getDBDictionary();
JDBCFetchConfiguration fetch = _store.getFetchConfiguration();
if (dict.simulateLocking) if (dict.simulateLocking)
return; return;
dict.assertSupport(dict.supportsSelectForUpdate, dict.assertSupport(dict.supportsSelectForUpdate,
@ -125,7 +126,7 @@ public class PessimisticLockManager
Select select = _store.getSQLFactory().newSelect(); Select select = _store.getSQLFactory().newSelect();
select.select(mapping.getPrimaryKeyColumns()); select.select(mapping.getPrimaryKeyColumns());
select.wherePrimaryKey(id, mapping, _store); select.wherePrimaryKey(id, mapping, _store);
SQLBuffer sql = select.toSelect(true, _store.getFetchConfiguration()); SQLBuffer sql = select.toSelect(true, fetch);
ensureStoreManagerTransaction(); ensureStoreManagerTransaction();
Connection conn = _store.getConnection(); Connection conn = _store.getConnection();
@ -133,7 +134,7 @@ public class PessimisticLockManager
ResultSet rs = null; ResultSet rs = null;
try { try {
stmnt = prepareStatement(conn, sql); stmnt = prepareStatement(conn, sql);
setTimeout(stmnt, timeout); dict.setTimeouts(stmnt, fetch, true);
rs = executeQuery(conn, stmnt, sql); rs = executeQuery(conn, stmnt, sql);
checkLock(rs, sm, timeout); checkLock(rs, sm, timeout);
} catch (SQLException se) { } catch (SQLException se) {
@ -175,23 +176,6 @@ public class PessimisticLockManager
return sql.prepareStatement(conn); 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 * This method is to provide override for non-JDBC or JDBC-like
* implementation of executing query. * implementation of executing query.

View File

@ -24,6 +24,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.Map; import java.util.Map;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.sql.DBDictionary; import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Result; import org.apache.openjpa.jdbc.sql.Result;
@ -101,6 +102,8 @@ public class PreparedSQLStoreQuery extends SQLStoreQuery {
for (int i = 0; i < params.length; i++) for (int i = 0; i < params.length; i++)
dict.setUnknown(stmnt, ++index, params[i], null); dict.setUnknown(stmnt, ++index, params[i], null);
dict.setTimeouts(stmnt, fetch, false);
ResultSet rs = stmnt.executeQuery(); ResultSet rs = stmnt.executeQuery();
SelectImpl cachedSelect = pq.getSelect(); SelectImpl cachedSelect = pq.getSelect();

View File

@ -34,6 +34,7 @@ import java.util.Map;
import java.util.Set; import java.util.Set;
import org.apache.commons.lang.StringUtils; 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.ClassMapping;
import org.apache.openjpa.jdbc.meta.MappingRepository; import org.apache.openjpa.jdbc.meta.MappingRepository;
import org.apache.openjpa.jdbc.meta.QueryResultMapping; import org.apache.openjpa.jdbc.meta.QueryResultMapping;
@ -166,6 +167,8 @@ public class SQLStoreQuery
if (stmnt != null) if (stmnt != null)
buf.setParameters(stmnt); buf.setParameters(stmnt);
dict.setTimeouts(stmnt, fetch, true);
int count = executeUpdate(store, conn, stmnt, buf); int count = executeUpdate(store, conn, stmnt, buf);
return Numbers.valueOf(count); return Numbers.valueOf(count);
@ -218,6 +221,7 @@ public class SQLStoreQuery
stmnt != null;) stmnt != null;)
dict.setUnknown(stmnt, ++index, i.next(), null); dict.setUnknown(stmnt, ++index, i.next(), null);
dict.setTimeouts(stmnt, fetch, false);
ResultSet rs = executeQuery(store, conn, stmnt, buf, paramList); ResultSet rs = executeQuery(store, conn, stmnt, buf, paramList);
ResultSetResult res = stmnt != null ? ResultSetResult res = stmnt != null ?
new ResultSetResult(conn, stmnt, rs, store) : new ResultSetResult(conn, stmnt, rs, store) :

View File

@ -467,6 +467,7 @@ public class TableJDBCSeq
PreparedStatement stmnt = null; PreparedStatement stmnt = null;
try { try {
stmnt = prepareStatement(conn, insert); stmnt = prepareStatement(conn, insert);
dict.setTimeouts(stmnt, _conf, true);
executeUpdate(_conf, conn, stmnt, insert, RowImpl.ACTION_INSERT); executeUpdate(_conf, conn, stmnt, insert, RowImpl.ACTION_INSERT);
} finally { } finally {
if (stmnt != null) if (stmnt != null)
@ -508,9 +509,11 @@ public class TableJDBCSeq
null, false, dict.supportsSelectForUpdate, 0, Long.MAX_VALUE, null, false, dict.supportsSelectForUpdate, 0, Long.MAX_VALUE,
false, true); false, true);
PreparedStatement stmnt = prepareStatement(conn, select); PreparedStatement stmnt = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
stmnt = prepareStatement(conn, select);
dict.setTimeouts(stmnt, _conf, false);
rs = executeQuery(_conf, conn, stmnt, select); rs = executeQuery(_conf, conn, stmnt, select);
return getSequence(rs, dict); return getSequence(rs, dict);
} finally { } finally {
@ -566,6 +569,7 @@ public class TableJDBCSeq
appendValue(Numbers.valueOf(cur), _seqColumn); appendValue(Numbers.valueOf(cur), _seqColumn);
stmnt = prepareStatement(conn, upd); stmnt = prepareStatement(conn, upd);
dict.setTimeouts(stmnt, _conf, true);
updates = executeUpdate(_conf, conn, stmnt, upd, RowImpl.ACTION_UPDATE); updates = executeUpdate(_conf, conn, stmnt, upd, RowImpl.ACTION_UPDATE);
} finally { } finally {
if (rs != null) if (rs != null)

View File

@ -24,6 +24,8 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.commons.lang.StringUtils; 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.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.meta.ClassMapping;
import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.Column;
@ -73,9 +75,9 @@ public class ClassNameDiscriminatorStrategy
Column col = disc.getColumns()[0]; Column col = disc.getColumns()[0];
DBDictionary dict = store.getDBDictionary(); DBDictionary dict = store.getDBDictionary();
JDBCFetchConfiguration fetch = store.getFetchConfiguration();
SQLBuffer select = dict.toSelect(new SQLBuffer(dict).append(col), SQLBuffer select = dict.toSelect(new SQLBuffer(dict).append(col),
store.getFetchConfiguration(), fetch, new SQLBuffer(dict).append(col.getTable()), null, null,
new SQLBuffer(dict).append(col.getTable()), null, null,
null, null, true, false, 0, Long.MAX_VALUE); null, null, true, false, 0, Long.MAX_VALUE);
Log log = disc.getMappingRepository().getLog(); Log log = disc.getMappingRepository().getLog();
@ -88,6 +90,7 @@ public class ClassNameDiscriminatorStrategy
ResultSet rs = null; ResultSet rs = null;
try { try {
stmnt = select.prepareStatement(conn); stmnt = select.prepareStatement(conn);
dict.setTimeouts(stmnt, fetch, false);
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
String className; String className;
while (rs.next()) { while (rs.next()) {

View File

@ -23,6 +23,7 @@ import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.meta.JavaSQLTypes; import org.apache.openjpa.jdbc.meta.JavaSQLTypes;
@ -142,20 +143,23 @@ abstract class MaxEmbeddedLobFieldStrategy
public void customUpdate(OpenJPAStateManager sm, JDBCStore store) public void customUpdate(OpenJPAStateManager sm, JDBCStore store)
throws SQLException { throws SQLException {
JDBCFetchConfiguration fetch = store.getFetchConfiguration();
// select existing value for update // select existing value for update
Column col = field.getColumns()[0]; Column col = field.getColumns()[0];
Select sel = store.getSQLFactory().newSelect(); Select sel = store.getSQLFactory().newSelect();
sel.select(col); sel.select(col);
field.wherePrimaryKey(sel, sm, store); field.wherePrimaryKey(sel, sm, store);
SQLBuffer sql = sel.toSelect(true, store.getFetchConfiguration()); SQLBuffer sql = sel.toSelect(true, fetch);
Connection conn = store.getConnection(); Connection conn = store.getConnection();
DBDictionary dict = store.getDBDictionary();
PreparedStatement stmnt = null; PreparedStatement stmnt = null;
ResultSet rs = null; ResultSet rs = null;
try { try {
stmnt = sql.prepareStatement(conn, stmnt = sql.prepareStatement(conn,
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE); ResultSet.CONCUR_UPDATABLE);
dict.setTimeouts(stmnt, fetch, true);
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
rs.next(); rs.next();

View File

@ -235,7 +235,7 @@ public class TableSchemaFactory
+ " (" + _pkColumn + ", " + _schemaColumn + ") VALUES (?, ?)"); + " (" + _pkColumn + ", " + _schemaColumn + ") VALUES (?, ?)");
dict.setInt(stmnt, 1, 1, _pkColumn); dict.setInt(stmnt, 1, 1, _pkColumn);
dict.setNull(stmnt, 2, _schemaColumn.getType(), _schemaColumn); dict.setNull(stmnt, 2, _schemaColumn.getType(), _schemaColumn);
dict.setTimeouts(stmnt, _conf, true);
stmnt.executeUpdate(); stmnt.executeUpdate();
} finally { } finally {
if (stmnt != null) if (stmnt != null)
@ -290,6 +290,7 @@ public class TableSchemaFactory
conn.setAutoCommit(true); conn.setAutoCommit(true);
stmnt = select.prepareStatement(conn); stmnt = select.prepareStatement(conn);
dict.setQueryTimeout(stmnt, _conf.getQueryTimeout());
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
rs.next(); rs.next();
String schema = (_schemaColumn.getType() == Types.CLOB) ? String schema = (_schemaColumn.getType() == Types.CLOB) ?
@ -353,12 +354,14 @@ public class TableSchemaFactory
else else
dict.setString(stmnt, 1, schema, _schemaColumn); dict.setString(stmnt, 1, schema, _schemaColumn);
dict.setInt(stmnt, 2, 1, _pkColumn); dict.setInt(stmnt, 2, 1, _pkColumn);
dict.setTimeouts(stmnt, _conf, true);
stmnt.executeUpdate(); stmnt.executeUpdate();
} else { } else {
stmnt = conn.prepareStatement(update, stmnt = conn.prepareStatement(update,
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE); ResultSet.CONCUR_UPDATABLE);
dict.setInt(stmnt, 1, 1, _pkColumn); dict.setInt(stmnt, 1, 1, _pkColumn);
dict.setTimeouts(stmnt, _conf, true);
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
rs.next(); rs.next();
dict.putString(rs.getClob(1), schema); dict.putString(rs.getClob(1), schema);

View File

@ -843,6 +843,10 @@ public class DB2Dictionary
if (subtype == StoreException.LOCK && errorState.equals("57033") if (subtype == StoreException.LOCK && errorState.equals("57033")
&& ex.getMessage().indexOf("80") != -1) { && ex.getMessage().indexOf("80") != -1) {
recoverable = Boolean.TRUE; 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; return recoverable;

View File

@ -109,6 +109,7 @@ import org.apache.openjpa.util.ObjectExistsException;
import org.apache.openjpa.util.ObjectNotFoundException; import org.apache.openjpa.util.ObjectNotFoundException;
import org.apache.openjpa.util.OpenJPAException; import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.OptimisticException; import org.apache.openjpa.util.OptimisticException;
import org.apache.openjpa.util.QueryException;
import org.apache.openjpa.util.ReferentialIntegrityException; import org.apache.openjpa.util.ReferentialIntegrityException;
import org.apache.openjpa.util.Serialization; import org.apache.openjpa.util.Serialization;
import org.apache.openjpa.util.StoreException; import org.apache.openjpa.util.StoreException;
@ -3649,7 +3650,7 @@ public class DBDictionary
stmnt.setString(idx++, schemaName.toUpperCase()); stmnt.setString(idx++, schemaName.toUpperCase());
if (sequenceName != null) if (sequenceName != null)
stmnt.setString(idx++, sequenceName); stmnt.setString(idx++, sequenceName);
setQueryTimeout(stmnt, conf.getQueryTimeout());
rs = executeQuery(conn, stmnt, str); rs = executeQuery(conn, stmnt, str);
return getSequence(rs); return getSequence(rs);
} finally { } finally {
@ -4046,6 +4047,7 @@ public class DBDictionary
PreparedStatement stmnt = prepareStatement(conn, query); PreparedStatement stmnt = prepareStatement(conn, query);
ResultSet rs = null; ResultSet rs = null;
try { try {
setQueryTimeout(stmnt, conf.getQueryTimeout());
rs = executeQuery(conn, stmnt, query); rs = executeQuery(conn, stmnt, query);
return getKey(rs, col); return getKey(rs, col);
} finally { } 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 // ConnectionDecorator implementation
////////////////////////////////////// //////////////////////////////////////
@ -4276,6 +4348,9 @@ public class DBDictionary
case StoreException.REFERENTIAL_INTEGRITY: case StoreException.REFERENTIAL_INTEGRITY:
storeEx = new ReferentialIntegrityException(msg); storeEx = new ReferentialIntegrityException(msg);
break; break;
case StoreException.QUERY:
storeEx = new QueryException(msg);
break;
default: default:
storeEx = new StoreException(msg); storeEx = new StoreException(msg);
} }
@ -4362,6 +4437,7 @@ public class DBDictionary
stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(), stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(),
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE); ResultSet.CONCUR_UPDATABLE);
setTimeouts(stmnt, store.getFetchConfiguration(), true);
res = stmnt.executeQuery(); res = stmnt.executeQuery();
if (!res.next()) { if (!res.next()) {
throw new InternalException(_loc.get("stream-exception")); throw new InternalException(_loc.get("stream-exception"));
@ -4395,6 +4471,7 @@ public class DBDictionary
stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(), stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(),
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE); ResultSet.CONCUR_UPDATABLE);
setTimeouts(stmnt, store.getFetchConfiguration(), true);
res = stmnt.executeQuery(); res = stmnt.executeQuery();
if (!res.next()) { if (!res.next()) {
throw new InternalException(_loc.get("stream-exception")); throw new InternalException(_loc.get("stream-exception"));

View File

@ -113,7 +113,7 @@ public class DerbyDictionary
int errorCode = ex.getErrorCode(); int errorCode = ex.getErrorCode();
if (errorStates.contains(errorState)) { if (errorStates.contains(errorState)) {
recoverable = Boolean.FALSE; recoverable = Boolean.FALSE;
if (subtype == StoreException.LOCK && errorCode < 30000) { if ((subtype == StoreException.LOCK || subtype == StoreException.QUERY) && errorCode < 30000) {
recoverable = Boolean.TRUE; recoverable = Boolean.TRUE;
} }
} }

View File

@ -655,7 +655,7 @@ public class OracleDictionary
setString(stmnt, idx++, schemaName.toUpperCase(), null); setString(stmnt, idx++, schemaName.toUpperCase(), null);
if (tableName != null) if (tableName != null)
setString(stmnt, idx++, tableName.toUpperCase(), null); setString(stmnt, idx++, tableName.toUpperCase(), null);
setTimeouts(stmnt, conf, false);
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
List pkList = new ArrayList(); List pkList = new ArrayList();
while (rs != null && rs.next()) while (rs != null && rs.next())
@ -703,6 +703,7 @@ public class OracleDictionary
if (tableName != null) if (tableName != null)
setString(stmnt, idx++, tableName.toUpperCase(), null); setString(stmnt, idx++, tableName.toUpperCase(), null);
setTimeouts(stmnt, conf, false);
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
List idxList = new ArrayList(); List idxList = new ArrayList();
while (rs != null && rs.next()) while (rs != null && rs.next())
@ -769,7 +770,7 @@ public class OracleDictionary
setString(stmnt, idx++, schemaName.toUpperCase(), null); setString(stmnt, idx++, schemaName.toUpperCase(), null);
if (tableName != null) if (tableName != null)
setString(stmnt, idx++, tableName.toUpperCase(), null); setString(stmnt, idx++, tableName.toUpperCase(), null);
setTimeouts(stmnt, conf, false);
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
List fkList = new ArrayList(); List fkList = new ArrayList();
while (rs != null && rs.next()) while (rs != null && rs.next())
@ -888,6 +889,7 @@ public class OracleDictionary
+ ".currval FROM DUAL"); + ".currval FROM DUAL");
ResultSet rs = null; ResultSet rs = null;
try { try {
setTimeouts(stmnt, conf, false);
rs = stmnt.executeQuery(); rs = stmnt.executeQuery();
rs.next(); rs.next();
return Numbers.valueOf(rs.getLong(1)); return Numbers.valueOf(rs.getLong(1));

View File

@ -32,6 +32,7 @@ import java.text.SimpleDateFormat;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date; import java.util.Date;
import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration;
import org.apache.openjpa.jdbc.kernel.JDBCStore; import org.apache.openjpa.jdbc.kernel.JDBCStore;
import org.apache.openjpa.jdbc.kernel.exps.FilterValue; import org.apache.openjpa.jdbc.kernel.exps.FilterValue;
import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.Column;
@ -382,14 +383,16 @@ public class PostgresDictionary
private void updatePostgresBlob(Row row, Column col, JDBCStore store, private void updatePostgresBlob(Row row, Column col, JDBCStore store,
Object ob, Select sel) throws SQLException { 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; ResultSet res = null;
DelegatingConnection conn = DelegatingConnection conn =
(DelegatingConnection) store.getConnection(); (DelegatingConnection) store.getConnection();
PreparedStatement stmnt = null; PreparedStatement stmnt = null;
try { try {
stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(), stmnt = sql.prepareStatement(conn, fetch,
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
setTimeouts(stmnt, fetch, true);
res = stmnt.executeQuery(); res = stmnt.executeQuery();
if (!res.next()) { if (!res.next()) {
throw new InternalException(_loc.get("stream-exception")); throw new InternalException(_loc.get("stream-exception"));
@ -443,14 +446,16 @@ public class PostgresDictionary
} }
public void deleteStream(JDBCStore store, Select sel) throws SQLException { 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; ResultSet res = null;
DelegatingConnection conn = DelegatingConnection conn =
(DelegatingConnection) store.getConnection(); (DelegatingConnection) store.getConnection();
PreparedStatement stmnt = null; PreparedStatement stmnt = null;
try { try {
stmnt = sql.prepareStatement(conn, store.getFetchConfiguration(), stmnt = sql.prepareStatement(conn, fetch,
ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
setTimeouts(stmnt, fetch, true);
res = stmnt.executeQuery(); res = stmnt.executeQuery();
if (!res.next()) { if (!res.next()) {
throw new InternalException(_loc.get("stream-exception")); throw new InternalException(_loc.get("stream-exception"));

View File

@ -60,7 +60,7 @@ public class SQLErrorCodeReader {
storeErrorTypes.put("optimistic", StoreException.OPTIMISTIC); storeErrorTypes.put("optimistic", StoreException.OPTIMISTIC);
storeErrorTypes.put("referential-integrity", storeErrorTypes.put("referential-integrity",
StoreException.REFERENTIAL_INTEGRITY); StoreException.REFERENTIAL_INTEGRITY);
storeErrorTypes.put("query", StoreException.QUERY);
} }
private static final Localizer _loc = private static final Localizer _loc =

View File

@ -28,6 +28,7 @@ import org.apache.openjpa.kernel.OpenJPAStateManager;
import org.apache.openjpa.lib.util.Localizer.Message; import org.apache.openjpa.lib.util.Localizer.Message;
import org.apache.openjpa.util.LockException; import org.apache.openjpa.util.LockException;
import org.apache.openjpa.util.OpenJPAException; import org.apache.openjpa.util.OpenJPAException;
import org.apache.openjpa.util.QueryException;
import org.apache.openjpa.util.StoreException; import org.apache.openjpa.util.StoreException;
/** /**
@ -130,6 +131,8 @@ public class SQLExceptions {
if (storeEx.getSubtype() == StoreException.LOCK) { if (storeEx.getSubtype() == StoreException.LOCK) {
LockException lockEx = (LockException) storeEx; LockException lockEx = (LockException) storeEx;
lockEx.setLockLevel(level); lockEx.setLockLevel(level);
} else if (storeEx.getSubtype() == StoreException.QUERY) {
QueryException QueryEx = (QueryException) storeEx;
} }
return storeEx; return storeEx;
} }

View File

@ -322,6 +322,7 @@ public class SelectImpl
stmnt = prepareStatement(conn, sql, null, stmnt = prepareStatement(conn, sql, null,
ResultSet.TYPE_FORWARD_ONLY, ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY, false); ResultSet.CONCUR_READ_ONLY, false);
_dict.setQueryTimeout(stmnt, store.getFetchConfiguration().getQueryTimeout());
rs = executeQuery(conn, stmnt, sql, false, store); rs = executeQuery(conn, stmnt, sql, false, store);
return getCount(rs); return getCount(rs);
} finally { } finally {
@ -377,7 +378,7 @@ public class SelectImpl
else else
stmnt = prepareStatement(conn, sql, null, rsType, -1, false); stmnt = prepareStatement(conn, sql, null, rsType, -1, false);
setTimeout(stmnt, forUpdate, fetch); _dict.setTimeouts(stmnt, fetch, forUpdate);
rs = executeQuery(conn, stmnt, sql, isLRS, store); rs = executeQuery(conn, stmnt, sql, isLRS, store);
} catch (SQLException se) { } catch (SQLException se) {
@ -448,27 +449,6 @@ public class SelectImpl
return conn.prepareStatement(sql); 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 * This method is to provide override for non-JDBC or JDBC-like
* implementation of executing query. * implementation of executing query.

View File

@ -29,11 +29,12 @@
<sql-state-codes> <sql-state-codes>
<dictionary class="org.apache.openjpa.jdbc.sql.DB2Dictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.DB2Dictionary">
<lock>40001,57033,57014</lock> <lock>40001,57033</lock>
<referential-integrity>23502,42912,23001,23504,23511,23512,23513,23515,23520,23505</referential-integrity> <referential-integrity>23502,42912,23001,23504,23511,23512,23513,23515,23520,23505</referential-integrity>
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query>57014</query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.DerbyDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.DerbyDictionary">
@ -42,6 +43,7 @@
<object-exists>23505</object-exists> <object-exists>23505</object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query>XCL52</query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.SQLServerDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.SQLServerDictionary">
@ -50,6 +52,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic>1205</optimistic> <optimistic>1205</optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.SybaseDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.SybaseDictionary">
@ -58,6 +61,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic>1205</optimistic> <optimistic>1205</optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.AccessDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.AccessDictionary">
@ -66,6 +70,7 @@
<object-exists>23505,456c</object-exists> <object-exists>23505,456c</object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic>40XL1,40001</optimistic> <optimistic>40XL1,40001</optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.CacheDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.CacheDictionary">
@ -74,6 +79,7 @@
<object-exists>23505,456c</object-exists> <object-exists>23505,456c</object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic>40XL1,40001</optimistic> <optimistic>40XL1,40001</optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.EmpressDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.EmpressDictionary">
@ -82,6 +88,7 @@
<object-exists>23505,456c</object-exists> <object-exists>23505,456c</object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic>40XL1,40001</optimistic> <optimistic>40XL1,40001</optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.FoxProDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.FoxProDictionary">
@ -90,6 +97,7 @@
<object-exists>23505,456c</object-exists> <object-exists>23505,456c</object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic>40XL1,40001</optimistic> <optimistic>40XL1,40001</optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.H2Dictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.H2Dictionary">
@ -98,6 +106,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.HSQLDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.HSQLDictionary">
@ -106,6 +115,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.InformixDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.InformixDictionary">
@ -114,6 +124,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.InterbaseDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.InterbaseDictionary">
@ -122,6 +133,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.FirebirdDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.FirebirdDictionary">
@ -130,6 +142,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.JDataStoreDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.JDataStoreDictionary">
@ -138,6 +151,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.MySQLDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.MySQLDictionary">
@ -146,6 +160,7 @@
<object-exists>23000</object-exists> <object-exists>23000</object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic>41000,1205,1213</optimistic> <optimistic>41000,1205,1213</optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.OracleDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.OracleDictionary">
@ -154,6 +169,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.PointbaseDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.PointbaseDictionary">
@ -162,6 +178,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic></optimistic> <optimistic></optimistic>
<query></query>
</dictionary> </dictionary>
<dictionary class="org.apache.openjpa.jdbc.sql.PostgresDictionary"> <dictionary class="org.apache.openjpa.jdbc.sql.PostgresDictionary">
@ -170,6 +187,7 @@
<object-exists></object-exists> <object-exists></object-exists>
<object-not-found></object-not-found> <object-not-found></object-not-found>
<optimistic>55P03</optimistic> <optimistic>55P03</optimistic>
<query></query>
</dictionary> </dictionary>
</sql-state-codes> </sql-state-codes>