mirror of https://github.com/apache/openjpa.git
OPENJPA-477 Making StoreManager more flexible and extensible
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@614763 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
8d18daabd7
commit
a8f6d3c116
|
@ -181,7 +181,7 @@ public abstract class AbstractUpdateManager
|
||||||
/**
|
/**
|
||||||
* Recursive method to insert the given instance, base class first.
|
* Recursive method to insert the given instance, base class first.
|
||||||
*/
|
*/
|
||||||
private void insert(OpenJPAStateManager sm, ClassMapping mapping,
|
protected void insert(OpenJPAStateManager sm, ClassMapping mapping,
|
||||||
RowManager rowMgr, JDBCStore store, Collection customs)
|
RowManager rowMgr, JDBCStore store, Collection customs)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
Boolean custom = mapping.isCustomInsert(sm, store);
|
Boolean custom = mapping.isCustomInsert(sm, store);
|
||||||
|
@ -228,7 +228,7 @@ public abstract class AbstractUpdateManager
|
||||||
/**
|
/**
|
||||||
* Recursive method to delete the given instance, base class last.
|
* Recursive method to delete the given instance, base class last.
|
||||||
*/
|
*/
|
||||||
private void delete(OpenJPAStateManager sm, ClassMapping mapping,
|
protected void delete(OpenJPAStateManager sm, ClassMapping mapping,
|
||||||
RowManager rowMgr, JDBCStore store, Collection customs)
|
RowManager rowMgr, JDBCStore store, Collection customs)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
Boolean custom = mapping.isCustomDelete(sm, store);
|
Boolean custom = mapping.isCustomDelete(sm, store);
|
||||||
|
@ -271,7 +271,7 @@ public abstract class AbstractUpdateManager
|
||||||
/**
|
/**
|
||||||
* Recursive method to update the given instance.
|
* Recursive method to update the given instance.
|
||||||
*/
|
*/
|
||||||
private void update(OpenJPAStateManager sm, BitSet dirty,
|
protected void update(OpenJPAStateManager sm, BitSet dirty,
|
||||||
ClassMapping mapping, RowManager rowMgr, JDBCStore store,
|
ClassMapping mapping, RowManager rowMgr, JDBCStore store,
|
||||||
Collection customs) throws SQLException {
|
Collection customs) throws SQLException {
|
||||||
Boolean custom = mapping.isCustomUpdate(sm, store);
|
Boolean custom = mapping.isCustomUpdate(sm, store);
|
||||||
|
@ -300,7 +300,7 @@ public abstract class AbstractUpdateManager
|
||||||
/**
|
/**
|
||||||
* Update version and discriminator indicators.
|
* Update version and discriminator indicators.
|
||||||
*/
|
*/
|
||||||
private void updateIndicators(OpenJPAStateManager sm, ClassMapping mapping,
|
protected void updateIndicators(OpenJPAStateManager sm, ClassMapping mapping,
|
||||||
RowManager rowMgr, JDBCStore store, Collection customs,
|
RowManager rowMgr, JDBCStore store, Collection customs,
|
||||||
boolean versionUpdateOnly) throws SQLException {
|
boolean versionUpdateOnly) throws SQLException {
|
||||||
while (mapping.getJoinablePCSuperclassMapping() != null)
|
while (mapping.getJoinablePCSuperclassMapping() != null)
|
||||||
|
|
|
@ -140,7 +140,7 @@ public class JDBCBrokerFactory
|
||||||
/**
|
/**
|
||||||
* Synchronize the mappings of the classes listed in the configuration.
|
* Synchronize the mappings of the classes listed in the configuration.
|
||||||
*/
|
*/
|
||||||
private void synchronizeMappings(ClassLoader loader) {
|
protected void synchronizeMappings(ClassLoader loader) {
|
||||||
JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
|
JDBCConfiguration conf = (JDBCConfiguration) getConfiguration();
|
||||||
String action = conf.getSynchronizeMappings();
|
String action = conf.getSynchronizeMappings();
|
||||||
if (StringUtils.isEmpty(action))
|
if (StringUtils.isEmpty(action))
|
||||||
|
|
|
@ -272,7 +272,7 @@ public class JDBCStoreManager
|
||||||
/**
|
/**
|
||||||
* Initialize a newly-loaded instance.
|
* Initialize a newly-loaded instance.
|
||||||
*/
|
*/
|
||||||
private boolean initializeState(OpenJPAStateManager sm, PCState state,
|
protected boolean initializeState(OpenJPAStateManager sm, PCState state,
|
||||||
JDBCFetchConfiguration fetch, ConnectionInfo info)
|
JDBCFetchConfiguration fetch, ConnectionInfo info)
|
||||||
throws ClassNotFoundException, SQLException {
|
throws ClassNotFoundException, SQLException {
|
||||||
Object oid = sm.getObjectId();
|
Object oid = sm.getObjectId();
|
||||||
|
@ -294,7 +294,7 @@ public class JDBCStoreManager
|
||||||
Select.SUBS_EXACT);
|
Select.SUBS_EXACT);
|
||||||
if (res == null && !selectPrimaryKey(sm, mapping, fetch))
|
if (res == null && !selectPrimaryKey(sm, mapping, fetch))
|
||||||
return false;
|
return false;
|
||||||
if (res != null && !res.next())
|
if (isEmptyResult(res))
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
ClassMapping[] mappings = mapping.
|
ClassMapping[] mappings = mapping.
|
||||||
|
@ -311,16 +311,14 @@ public class JDBCStoreManager
|
||||||
} else
|
} else
|
||||||
res = getInitializeStateUnionResult(sm, mapping, mappings,
|
res = getInitializeStateUnionResult(sm, mapping, mappings,
|
||||||
fetch);
|
fetch);
|
||||||
if (res != null && !res.next())
|
if (isEmptyResult(res))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// figure out what type of object this is; the state manager
|
// figure out what type of object this is; the state manager
|
||||||
// only guarantees to provide a base class
|
// only guarantees to provide a base class
|
||||||
Class type;
|
Class type;
|
||||||
if (res == null)
|
if ((type = getType(res, mapping)) == null) {
|
||||||
type = mapping.getDescribedType();
|
|
||||||
else {
|
|
||||||
if (res.getBaseMapping() != null)
|
if (res.getBaseMapping() != null)
|
||||||
mapping = res.getBaseMapping();
|
mapping = res.getBaseMapping();
|
||||||
res.startDataRequest(mapping.getDiscriminator());
|
res.startDataRequest(mapping.getDiscriminator());
|
||||||
|
@ -342,7 +340,7 @@ public class JDBCStoreManager
|
||||||
// re-get the mapping in case the instance was a subclass
|
// re-get the mapping in case the instance was a subclass
|
||||||
mapping = (ClassMapping) sm.getMetaData();
|
mapping = (ClassMapping) sm.getMetaData();
|
||||||
load(mapping, sm, fetch, res);
|
load(mapping, sm, fetch, res);
|
||||||
mapping.getVersion().afterLoad(sm, this);
|
getVersion(mapping, sm, res);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -351,6 +349,35 @@ public class JDBCStoreManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of getting version from the result set.
|
||||||
|
*/
|
||||||
|
protected void getVersion(ClassMapping mapping, OpenJPAStateManager sm,
|
||||||
|
Result res) throws SQLException {
|
||||||
|
mapping.getVersion().afterLoad(sm, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of checking whether the result set is empty or not.
|
||||||
|
*/
|
||||||
|
protected boolean isEmptyResult(Result res) throws SQLException {
|
||||||
|
if (res != null && !res.next())
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of getting type from the result set.
|
||||||
|
*/
|
||||||
|
protected Class getType(Result res, ClassMapping mapping){
|
||||||
|
if (res == null)
|
||||||
|
return mapping.getDescribedType();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow the mapping to custom load data. Return null if the mapping
|
* Allow the mapping to custom load data. Return null if the mapping
|
||||||
* does not use custom loading.
|
* does not use custom loading.
|
||||||
|
@ -427,7 +454,7 @@ public class JDBCStoreManager
|
||||||
sel.wherePrimaryKey(sm.getObjectId(), base, this);
|
sel.wherePrimaryKey(sm.getObjectId(), base, this);
|
||||||
Result exists = sel.execute(this, fetch);
|
Result exists = sel.execute(this, fetch);
|
||||||
try {
|
try {
|
||||||
if (!exists.next())
|
if (isEmptyResult(exists))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// record locked?
|
// record locked?
|
||||||
|
@ -478,7 +505,7 @@ public class JDBCStoreManager
|
||||||
sel.wherePrimaryKey(sm.getObjectId(), mapping, this);
|
sel.wherePrimaryKey(sm.getObjectId(), mapping, this);
|
||||||
res = sel.execute(this, jfetch, lockLevel);
|
res = sel.execute(this, jfetch, lockLevel);
|
||||||
try {
|
try {
|
||||||
if (!res.next())
|
if (isEmptyResult(res))
|
||||||
return false;
|
return false;
|
||||||
load(mapping, sm, jfetch, res);
|
load(mapping, sm, jfetch, res);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -499,8 +499,8 @@ public class JDBCStoreQuery
|
||||||
for (int i = 0; i < sql.length; i++) {
|
for (int i = 0; i < sql.length; i++) {
|
||||||
stmnt = null;
|
stmnt = null;
|
||||||
try {
|
try {
|
||||||
stmnt = sql[i].prepareStatement(conn);
|
stmnt = prepareStatement(conn, sql[i]);
|
||||||
count += stmnt.executeUpdate();
|
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(),
|
||||||
_store.getDBDictionary());
|
_store.getDBDictionary());
|
||||||
|
@ -649,4 +649,22 @@ public class JDBCStoreQuery
|
||||||
sql[i] = ((Select) sels.get(i)).toSelect(false, fetch).getSQL(true);
|
sql[i] = ((Select) sels.get(i)).toSelect(false, fetch).getSQL(true);
|
||||||
return sql;
|
return sql;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of executing update.
|
||||||
|
*/
|
||||||
|
protected int executeUpdate(Connection conn, PreparedStatement stmnt,
|
||||||
|
SQLBuffer sqlBuf, boolean isUpdate) throws SQLException {
|
||||||
|
return stmnt.executeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareStatement(Connection conn, SQLBuffer sql)
|
||||||
|
throws SQLException {
|
||||||
|
return sql.prepareStatement(conn);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,18 +132,10 @@ public class PessimisticLockManager
|
||||||
PreparedStatement stmnt = null;
|
PreparedStatement stmnt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
stmnt = sql.prepareStatement(conn);
|
stmnt = prepareStatement(conn, sql);
|
||||||
if (timeout >= 0 && dict.supportsQueryTimeout) {
|
setTimeout(stmnt, timeout);
|
||||||
if (timeout < 1000) {
|
rs = executeQuery(conn, stmnt, sql);
|
||||||
timeout = 1000;
|
checkLock(rs, sm);
|
||||||
if (log.isWarnEnabled())
|
|
||||||
log.warn(_loc.get("millis-query-timeout"));
|
|
||||||
}
|
|
||||||
stmnt.setQueryTimeout(timeout / 1000);
|
|
||||||
}
|
|
||||||
rs = stmnt.executeQuery();
|
|
||||||
if (!rs.next())
|
|
||||||
throw new LockException(sm.getManagedInstance());
|
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
throw SQLExceptions.getStore(se, dict);
|
throw SQLExceptions.getStore(se, dict);
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -168,4 +160,54 @@ public class PessimisticLockManager
|
||||||
log.info(_loc.get("start-trans-for-lock"));
|
log.info(_loc.get("start-trans-for-lock"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public JDBCStore getStore() {
|
||||||
|
return _store;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareStatement(Connection conn, SQLBuffer sql)
|
||||||
|
throws SQLException {
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt,
|
||||||
|
SQLBuffer sql) throws SQLException {
|
||||||
|
return stmnt.executeQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of checking lock from the result set.
|
||||||
|
*/
|
||||||
|
protected void checkLock(ResultSet rs, OpenJPAStateManager sm)
|
||||||
|
throws SQLException {
|
||||||
|
if (!rs.next())
|
||||||
|
throw new LockException(sm.getManagedInstance());
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ import org.apache.openjpa.lib.util.Localizer;
|
||||||
import org.apache.openjpa.util.ApplicationIds;
|
import org.apache.openjpa.util.ApplicationIds;
|
||||||
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.meta.ClassMetaData;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic prepared statement manager implementation.
|
* Basic prepared statement manager implementation.
|
||||||
|
@ -89,12 +88,13 @@ public class PreparedStatementManagerImpl
|
||||||
|
|
||||||
// prepare statement
|
// prepare statement
|
||||||
String sql = row.getSQL(_dict);
|
String sql = row.getSQL(_dict);
|
||||||
PreparedStatement stmnt = _conn.prepareStatement(sql);
|
PreparedStatement stmnt = prepareStatement(sql);
|
||||||
|
|
||||||
// setup parameters and execute statement
|
// setup parameters and execute statement
|
||||||
|
if (stmnt != null)
|
||||||
row.flush(stmnt, _dict, _store);
|
row.flush(stmnt, _dict, _store);
|
||||||
try {
|
try {
|
||||||
int count = stmnt.executeUpdate();
|
int count = executeUpdate(stmnt, sql, row);
|
||||||
if (count != 1) {
|
if (count != 1) {
|
||||||
Object failed = row.getFailedObject();
|
Object failed = row.getFailedObject();
|
||||||
if (failed != null)
|
if (failed != null)
|
||||||
|
@ -107,6 +107,7 @@ public class PreparedStatementManagerImpl
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
throw SQLExceptions.getStore(se, row.getFailedObject(), _dict);
|
throw SQLExceptions.getStore(se, row.getFailedObject(), _dict);
|
||||||
} finally {
|
} finally {
|
||||||
|
if (stmnt != null)
|
||||||
try { stmnt.close(); } catch (SQLException se) {}
|
try { stmnt.close(); } catch (SQLException se) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,4 +129,22 @@ public class PreparedStatementManagerImpl
|
||||||
|
|
||||||
public void flush() {
|
public void flush() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of executing update.
|
||||||
|
*/
|
||||||
|
protected int executeUpdate(PreparedStatement stmnt, String sql,
|
||||||
|
RowImpl row) throws SQLException {
|
||||||
|
return stmnt.executeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareStatement(String sql)
|
||||||
|
throws SQLException {
|
||||||
|
return _conn.prepareStatement(sql);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.io.StreamTokenizer;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.PreparedStatement;
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -157,7 +158,7 @@ public class SQLStoreQuery
|
||||||
/**
|
/**
|
||||||
* Executes the filter as a SQL query.
|
* Executes the filter as a SQL query.
|
||||||
*/
|
*/
|
||||||
private static class SQLExecutor
|
protected static class SQLExecutor
|
||||||
extends AbstractExecutor {
|
extends AbstractExecutor {
|
||||||
|
|
||||||
private final ClassMetaData _meta;
|
private final ClassMetaData _meta;
|
||||||
|
@ -224,20 +225,14 @@ public class SQLStoreQuery
|
||||||
|
|
||||||
PreparedStatement stmnt = null;
|
PreparedStatement stmnt = null;
|
||||||
try {
|
try {
|
||||||
stmnt = buf.prepareCall(conn);
|
stmnt = prepareCall(conn, buf);
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (Iterator i = paramList.iterator(); i.hasNext();)
|
for (Iterator i = paramList.iterator(); i.hasNext() &&
|
||||||
|
stmnt != null;)
|
||||||
dict.setUnknown(stmnt, ++index, i.next(), null);
|
dict.setUnknown(stmnt, ++index, i.next(), null);
|
||||||
|
|
||||||
int count = 0;
|
int count = executeUpdate(store, conn, stmnt, buf);
|
||||||
if (_call && stmnt.execute() == false) {
|
|
||||||
count = stmnt.getUpdateCount();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// native insert, update, delete
|
|
||||||
count = stmnt.executeUpdate();
|
|
||||||
}
|
|
||||||
return Numbers.valueOf(count);
|
return Numbers.valueOf(count);
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
if (stmnt != null)
|
if (stmnt != null)
|
||||||
|
@ -276,20 +271,23 @@ public class SQLStoreQuery
|
||||||
try {
|
try {
|
||||||
// use the right method depending on sel vs. proc, lrs setting
|
// use the right method depending on sel vs. proc, lrs setting
|
||||||
if (_select && !range.lrs)
|
if (_select && !range.lrs)
|
||||||
stmnt = buf.prepareStatement(conn);
|
stmnt = prepareStatement(conn, buf);
|
||||||
else if (_select)
|
else if (_select)
|
||||||
stmnt = buf.prepareStatement(conn, fetch, -1, -1);
|
stmnt = prepareStatement(conn, buf, fetch, -1, -1);
|
||||||
else if (!range.lrs)
|
else if (!range.lrs)
|
||||||
stmnt = buf.prepareCall(conn);
|
stmnt = prepareCall(conn, buf);
|
||||||
else
|
else
|
||||||
stmnt = buf.prepareCall(conn, fetch, -1, -1);
|
stmnt = prepareCall(conn, buf, fetch, -1, -1);
|
||||||
|
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (Iterator i = paramList.iterator(); i.hasNext();)
|
for (Iterator i = paramList.iterator(); i.hasNext() &&
|
||||||
|
stmnt != null;)
|
||||||
dict.setUnknown(stmnt, ++index, i.next(), null);
|
dict.setUnknown(stmnt, ++index, i.next(), null);
|
||||||
|
|
||||||
ResultSetResult res = new ResultSetResult(conn, stmnt,
|
ResultSet rs = executeQuery(store, conn, stmnt, buf, paramList);
|
||||||
stmnt.executeQuery(), store);
|
ResultSetResult res = stmnt != null ?
|
||||||
|
new ResultSetResult(conn, stmnt, rs, store) :
|
||||||
|
new ResultSetResult(conn, rs, dict);
|
||||||
if (_resultMapping != null)
|
if (_resultMapping != null)
|
||||||
rop = new MappedQueryResultObjectProvider(_resultMapping,
|
rop = new MappedQueryResultObjectProvider(_resultMapping,
|
||||||
store, fetch, res);
|
store, fetch, res);
|
||||||
|
@ -319,5 +317,71 @@ public class SQLStoreQuery
|
||||||
public boolean isPacking(StoreQuery q) {
|
public boolean isPacking(StoreQuery q) {
|
||||||
return q.getContext().getCandidateType() == null;
|
return q.getContext().getCandidateType() == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing call statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareCall(Connection conn, SQLBuffer buf)
|
||||||
|
throws SQLException {
|
||||||
|
return buf.prepareCall(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of executing update.
|
||||||
|
*/
|
||||||
|
protected int executeUpdate(JDBCStore store, Connection conn,
|
||||||
|
PreparedStatement stmnt, SQLBuffer buf)
|
||||||
|
throws SQLException {
|
||||||
|
int count = 0;
|
||||||
|
if (_call && stmnt.execute() == false) {
|
||||||
|
count = stmnt.getUpdateCount();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// native insert, update, delete
|
||||||
|
count = stmnt.executeUpdate();
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing call statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareCall(Connection conn, SQLBuffer buf,
|
||||||
|
JDBCFetchConfiguration fetch, int rsType, int rsConcur)
|
||||||
|
throws SQLException {
|
||||||
|
return buf.prepareCall(conn, fetch, rsType, rsConcur);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareStatement(Connection conn,
|
||||||
|
SQLBuffer buf) throws SQLException {
|
||||||
|
return buf.prepareStatement(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareStatement(Connection conn,
|
||||||
|
SQLBuffer buf, JDBCFetchConfiguration fetch, int rsType,
|
||||||
|
int rsConcur) throws SQLException {
|
||||||
|
return buf.prepareStatement(conn, fetch, rsType, rsConcur);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of executing query.
|
||||||
|
*/
|
||||||
|
protected ResultSet executeQuery(JDBCStore store, Connection conn,
|
||||||
|
PreparedStatement stmnt, SQLBuffer buf, List paramList)
|
||||||
|
throws SQLException {
|
||||||
|
return stmnt.executeQuery();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,6 @@ import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
|
||||||
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
|
import org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl;
|
||||||
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;
|
||||||
import org.apache.openjpa.jdbc.schema.Index;
|
|
||||||
import org.apache.openjpa.jdbc.schema.PrimaryKey;
|
import org.apache.openjpa.jdbc.schema.PrimaryKey;
|
||||||
import org.apache.openjpa.jdbc.schema.Schema;
|
import org.apache.openjpa.jdbc.schema.Schema;
|
||||||
import org.apache.openjpa.jdbc.schema.SchemaGroup;
|
import org.apache.openjpa.jdbc.schema.SchemaGroup;
|
||||||
|
@ -38,6 +37,7 @@ import org.apache.openjpa.jdbc.schema.SchemaTool;
|
||||||
import org.apache.openjpa.jdbc.schema.Schemas;
|
import org.apache.openjpa.jdbc.schema.Schemas;
|
||||||
import org.apache.openjpa.jdbc.schema.Table;
|
import org.apache.openjpa.jdbc.schema.Table;
|
||||||
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
import org.apache.openjpa.jdbc.sql.DBDictionary;
|
||||||
|
import org.apache.openjpa.jdbc.sql.RowImpl;
|
||||||
import org.apache.openjpa.jdbc.sql.SQLBuffer;
|
import org.apache.openjpa.jdbc.sql.SQLBuffer;
|
||||||
import org.apache.openjpa.jdbc.sql.SQLExceptions;
|
import org.apache.openjpa.jdbc.sql.SQLExceptions;
|
||||||
import org.apache.openjpa.lib.conf.Configurable;
|
import org.apache.openjpa.lib.conf.Configurable;
|
||||||
|
@ -431,8 +431,8 @@ public class TableJDBCSeq
|
||||||
|
|
||||||
PreparedStatement stmnt = null;
|
PreparedStatement stmnt = null;
|
||||||
try {
|
try {
|
||||||
stmnt = insert.prepareStatement(conn);
|
stmnt = prepareStatement(conn, insert);
|
||||||
stmnt.executeUpdate();
|
executeUpdate(_conf, conn, stmnt, insert, RowImpl.ACTION_INSERT);
|
||||||
} finally {
|
} finally {
|
||||||
if (stmnt != null)
|
if (stmnt != null)
|
||||||
try { stmnt.close(); } catch (SQLException se) {}
|
try { stmnt.close(); } catch (SQLException se) {}
|
||||||
|
@ -464,16 +464,15 @@ 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 = select.prepareStatement(conn);
|
PreparedStatement stmnt = prepareStatement(conn, select);
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
rs = stmnt.executeQuery();
|
rs = executeQuery(_conf, conn, stmnt, select);
|
||||||
if (!rs.next())
|
return getSequence(rs, dict);
|
||||||
return -1;
|
|
||||||
return dict.getLong(rs, 1);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (rs != null)
|
if (rs != null)
|
||||||
try { rs.close(); } catch (SQLException se) {}
|
try { rs.close(); } catch (SQLException se) {}
|
||||||
|
if (stmnt != null)
|
||||||
try { stmnt.close(); } catch (SQLException se) {}
|
try { stmnt.close(); } catch (SQLException se) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -522,8 +521,8 @@ public class TableJDBCSeq
|
||||||
append(_seqColumn).append(" = ").
|
append(_seqColumn).append(" = ").
|
||||||
appendValue(Numbers.valueOf(cur), _seqColumn);
|
appendValue(Numbers.valueOf(cur), _seqColumn);
|
||||||
|
|
||||||
stmnt = upd.prepareStatement(conn);
|
stmnt = prepareStatement(conn, upd);
|
||||||
updates = stmnt.executeUpdate();
|
updates = executeUpdate(_conf, conn, stmnt, upd, RowImpl.ACTION_UPDATE);
|
||||||
} finally {
|
} finally {
|
||||||
if (rs != null)
|
if (rs != null)
|
||||||
try { rs.close(); } catch (SQLException se) {}
|
try { rs.close(); } catch (SQLException se) {}
|
||||||
|
@ -704,4 +703,41 @@ public class TableJDBCSeq
|
||||||
public long seq = 1L;
|
public long seq = 1L;
|
||||||
public long max = 0L;
|
public long max = 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareStatement(Connection conn, SQLBuffer buf)
|
||||||
|
throws SQLException {
|
||||||
|
return buf.prepareStatement(conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of executing update.
|
||||||
|
*/
|
||||||
|
protected int executeUpdate(JDBCConfiguration conf, Connection conn,
|
||||||
|
PreparedStatement stmnt, SQLBuffer buf, int opcode) throws SQLException {
|
||||||
|
return stmnt.executeUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of executing query.
|
||||||
|
*/
|
||||||
|
protected ResultSet executeQuery(JDBCConfiguration conf, Connection conn,
|
||||||
|
PreparedStatement stmnt, SQLBuffer buf) throws SQLException {
|
||||||
|
return stmnt.executeQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of getting sequence from the result set.
|
||||||
|
*/
|
||||||
|
protected long getSequence(ResultSet rs, DBDictionary dict) throws SQLException {
|
||||||
|
if (rs == null || !rs.next())
|
||||||
|
return -1;
|
||||||
|
return dict.getLong(rs, 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ import org.apache.openjpa.util.UserException;
|
||||||
*
|
*
|
||||||
* @author Abe White
|
* @author Abe White
|
||||||
*/
|
*/
|
||||||
class PCPath
|
public class PCPath
|
||||||
extends AbstractVal
|
extends AbstractVal
|
||||||
implements JDBCPath {
|
implements JDBCPath {
|
||||||
|
|
||||||
|
@ -549,7 +549,7 @@ class PCPath
|
||||||
/**
|
/**
|
||||||
* Expression state.
|
* Expression state.
|
||||||
*/
|
*/
|
||||||
private static class PathExpState
|
public static class PathExpState
|
||||||
extends ExpState {
|
extends ExpState {
|
||||||
|
|
||||||
public FieldMapping field = null;
|
public FieldMapping field = null;
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class Param
|
||||||
/**
|
/**
|
||||||
* Expression state.
|
* Expression state.
|
||||||
*/
|
*/
|
||||||
private static class ParamExpState
|
public static class ParamExpState
|
||||||
extends ConstExpState {
|
extends ConstExpState {
|
||||||
|
|
||||||
public Object sqlValue = null;
|
public Object sqlValue = null;
|
||||||
|
|
|
@ -87,7 +87,6 @@ import org.apache.openjpa.jdbc.schema.Unique;
|
||||||
import org.apache.openjpa.kernel.Filters;
|
import org.apache.openjpa.kernel.Filters;
|
||||||
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
import org.apache.openjpa.kernel.OpenJPAStateManager;
|
||||||
import org.apache.openjpa.kernel.exps.Path;
|
import org.apache.openjpa.kernel.exps.Path;
|
||||||
import org.apache.openjpa.kernel.exps.Literal;
|
|
||||||
import org.apache.openjpa.lib.conf.Configurable;
|
import org.apache.openjpa.lib.conf.Configurable;
|
||||||
import org.apache.openjpa.lib.conf.Configuration;
|
import org.apache.openjpa.lib.conf.Configuration;
|
||||||
import org.apache.openjpa.lib.jdbc.ConnectionDecorator;
|
import org.apache.openjpa.lib.jdbc.ConnectionDecorator;
|
||||||
|
@ -1982,7 +1981,7 @@ public class DBDictionary
|
||||||
ExpState state = val.initialize(sel, ctx, 0);
|
ExpState state = val.initialize(sel, ctx, 0);
|
||||||
// JDBC Paths are always PCPaths; PCPath implements Val
|
// JDBC Paths are always PCPaths; PCPath implements Val
|
||||||
ExpState pathState = ((Val) path).initialize(sel, ctx, 0);
|
ExpState pathState = ((Val) path).initialize(sel, ctx, 0);
|
||||||
val.calculateValue(sel, ctx, state, (Val) path, pathState);
|
calculateValue(val, sel, ctx, state, path, pathState);
|
||||||
|
|
||||||
// append the value with a null for the Select; i
|
// append the value with a null for the Select; i
|
||||||
// indicates that the
|
// indicates that the
|
||||||
|
@ -3476,7 +3475,7 @@ public class DBDictionary
|
||||||
if (str == null)
|
if (str == null)
|
||||||
return new Sequence[0];
|
return new Sequence[0];
|
||||||
|
|
||||||
PreparedStatement stmnt = conn.prepareStatement(str);
|
PreparedStatement stmnt = prepareStatement(conn, str);
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
int idx = 1;
|
int idx = 1;
|
||||||
|
@ -3485,17 +3484,15 @@ public class DBDictionary
|
||||||
if (sequenceName != null)
|
if (sequenceName != null)
|
||||||
stmnt.setString(idx++, sequenceName);
|
stmnt.setString(idx++, sequenceName);
|
||||||
|
|
||||||
rs = stmnt.executeQuery();
|
rs = executeQuery(conn, stmnt, str);
|
||||||
List seqList = new ArrayList();
|
return getSequence(rs);
|
||||||
while (rs.next())
|
|
||||||
seqList.add(newSequence(rs));
|
|
||||||
return (Sequence[]) seqList.toArray(new Sequence[seqList.size()]);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (rs != null)
|
if (rs != null)
|
||||||
try {
|
try {
|
||||||
rs.close();
|
rs.close();
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
}
|
}
|
||||||
|
if (stmnt != null)
|
||||||
try {
|
try {
|
||||||
stmnt.close();
|
stmnt.close();
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
|
@ -3880,19 +3877,15 @@ public class DBDictionary
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
PreparedStatement stmnt = conn.prepareStatement(query);
|
PreparedStatement stmnt = prepareStatement(conn, query);
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
rs = stmnt.executeQuery();
|
rs = executeQuery(conn, stmnt, query);
|
||||||
if (!rs.next())
|
return getKey(rs, col);
|
||||||
throw new StoreException(_loc.get("no-genkey"));
|
|
||||||
Object key = rs.getObject(1);
|
|
||||||
if (key == null)
|
|
||||||
log.warn(_loc.get("invalid-genkey", col));
|
|
||||||
return key;
|
|
||||||
} finally {
|
} finally {
|
||||||
if (rs != null)
|
if (rs != null)
|
||||||
try { rs.close(); } catch (SQLException se) {}
|
try { rs.close(); } catch (SQLException se) {}
|
||||||
|
if (stmnt != null)
|
||||||
try { stmnt.close(); } catch (SQLException se) {}
|
try { stmnt.close(); } catch (SQLException se) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4277,4 +4270,55 @@ public class DBDictionary
|
||||||
OpenJPAStateManager sm, ClassMapping cmd ) {
|
OpenJPAStateManager sm, ClassMapping cmd ) {
|
||||||
return disableBatch;
|
return disableBatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of executing query.
|
||||||
|
*/
|
||||||
|
protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt, String sql
|
||||||
|
) throws SQLException {
|
||||||
|
return stmnt.executeQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareStatement(Connection conn, String sql)
|
||||||
|
throws SQLException {
|
||||||
|
return conn.prepareStatement(sql);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of getting sequence from the result set.
|
||||||
|
*/
|
||||||
|
protected Sequence[] getSequence(ResultSet rs) throws SQLException {
|
||||||
|
List seqList = new ArrayList();
|
||||||
|
while (rs != null && rs.next())
|
||||||
|
seqList.add(newSequence(rs));
|
||||||
|
return (Sequence[]) seqList.toArray(new Sequence[seqList.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of getting key from the result set.
|
||||||
|
*/
|
||||||
|
protected Object getKey (ResultSet rs, Column col) throws SQLException {
|
||||||
|
if (!rs.next())
|
||||||
|
throw new StoreException(_loc.get("no-genkey"));
|
||||||
|
Object key = rs.getObject(1);
|
||||||
|
if (key == null)
|
||||||
|
log.warn(_loc.get("invalid-genkey", col));
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of calculating value.
|
||||||
|
*/
|
||||||
|
protected void calculateValue(Val val, Select sel, ExpContext ctx,
|
||||||
|
ExpState state, Path path, ExpState pathState) {
|
||||||
|
val.calculateValue(sel, ctx, state, (Val) path, pathState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,6 +91,17 @@ public class ResultSetResult
|
||||||
setStore(store);
|
setStore(store);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public ResultSetResult(Connection conn,
|
||||||
|
ResultSet rs, DBDictionary dict) {
|
||||||
|
_conn = conn;
|
||||||
|
_stmnt = null;
|
||||||
|
_rs = rs;
|
||||||
|
_dict = dict;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JDBC 2 constructor. Relies on being able to retrieve the statement
|
* JDBC 2 constructor. Relies on being able to retrieve the statement
|
||||||
* from the result set, and the connection from the statement.
|
* from the result set, and the connection from the statement.
|
||||||
|
|
|
@ -20,7 +20,6 @@ package org.apache.openjpa.jdbc.sql;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.sql.Array;
|
import java.sql.Array;
|
||||||
|
@ -57,10 +56,10 @@ import serp.util.Numbers;
|
||||||
public class RowImpl
|
public class RowImpl
|
||||||
implements Row, Cloneable {
|
implements Row, Cloneable {
|
||||||
|
|
||||||
protected static final Object NULL = new Object();
|
public static final Object NULL = new Object();
|
||||||
protected static final int VALID = 2 << 0;
|
protected static final int VALID = 2 << 0;
|
||||||
|
|
||||||
private static final int RAW = Integer.MIN_VALUE;
|
public static final int RAW = Integer.MIN_VALUE;
|
||||||
|
|
||||||
protected byte flags = 0;
|
protected byte flags = 0;
|
||||||
private final Column[] _cols;
|
private final Column[] _cols;
|
||||||
|
@ -950,4 +949,12 @@ public class RowImpl
|
||||||
if (isValid())
|
if (isValid())
|
||||||
row.setValid(true);
|
row.setValid(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object[] getVals() {
|
||||||
|
return _vals;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int[] getTypes() {
|
||||||
|
return _types;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -641,4 +641,12 @@ public final class SQLBuffer
|
||||||
return sub;
|
return sub;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setParameters(List params) {
|
||||||
|
_params = params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List getColumns() {
|
||||||
|
return _cols;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -297,10 +297,11 @@ public class SelectImpl
|
||||||
try {
|
try {
|
||||||
SQLBuffer sql = toSelectCount();
|
SQLBuffer sql = toSelectCount();
|
||||||
conn = store.getConnection();
|
conn = store.getConnection();
|
||||||
stmnt = sql.prepareStatement(conn);
|
stmnt = prepareStatement(conn, sql, null,
|
||||||
rs = stmnt.executeQuery();
|
ResultSet.TYPE_FORWARD_ONLY,
|
||||||
rs.next();
|
ResultSet.CONCUR_READ_ONLY, false);
|
||||||
return rs.getInt(1);
|
rs = executeQuery(conn, stmnt, sql, false, store);
|
||||||
|
return getCount(rs);
|
||||||
} finally {
|
} finally {
|
||||||
if (rs != null)
|
if (rs != null)
|
||||||
try { rs.close(); } catch (SQLException se) {}
|
try { rs.close(); } catch (SQLException se) {}
|
||||||
|
@ -342,31 +343,21 @@ public class SelectImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
SQLBuffer sql = toSelect(forUpdate, fetch);
|
SQLBuffer sql = toSelect(forUpdate, fetch);
|
||||||
int rsType = (isLRS() && supportsRandomAccess(forUpdate))
|
boolean isLRS = isLRS();
|
||||||
|
int rsType = (isLRS && supportsRandomAccess(forUpdate))
|
||||||
? -1 : ResultSet.TYPE_FORWARD_ONLY;
|
? -1 : ResultSet.TYPE_FORWARD_ONLY;
|
||||||
Connection conn = store.getConnection();
|
Connection conn = store.getConnection();
|
||||||
PreparedStatement stmnt = null;
|
PreparedStatement stmnt = null;
|
||||||
ResultSet rs = null;
|
ResultSet rs = null;
|
||||||
try {
|
try {
|
||||||
if (isLRS())
|
if (isLRS)
|
||||||
stmnt = sql.prepareStatement(conn, fetch, rsType, -1);
|
stmnt = prepareStatement(conn, sql, fetch, rsType, -1, true);
|
||||||
else
|
else
|
||||||
stmnt = sql.prepareStatement(conn, rsType, -1);
|
stmnt = prepareStatement(conn, sql, null, rsType, -1, false);
|
||||||
|
|
||||||
// if this is a locking select and the lock timeout is greater than
|
setTimeout(stmnt, forUpdate, fetch);
|
||||||
// the configured query timeout, use the lock timeout
|
|
||||||
if (forUpdate && _dict.supportsQueryTimeout && fetch != null
|
rs = executeQuery(conn, stmnt, sql, isLRS, store);
|
||||||
&& 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);
|
|
||||||
}
|
|
||||||
rs = stmnt.executeQuery();
|
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
// clean up statement
|
// clean up statement
|
||||||
if (stmnt != null)
|
if (stmnt != null)
|
||||||
|
@ -375,17 +366,8 @@ public class SelectImpl
|
||||||
throw se;
|
throw se;
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectResult res = new SelectResult(conn, stmnt, rs, _dict);
|
return getEagerResult(conn, stmnt, rs, store, fetch, forUpdate,
|
||||||
res.setSelect(this);
|
sql.getSQL());
|
||||||
res.setStore(store);
|
|
||||||
res.setLocking(forUpdate);
|
|
||||||
try {
|
|
||||||
addEagerResults(res, this, store, fetch);
|
|
||||||
} catch (SQLException se) {
|
|
||||||
res.close();
|
|
||||||
throw se;
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -423,6 +405,80 @@ public class SelectImpl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of preparing statement.
|
||||||
|
*/
|
||||||
|
protected PreparedStatement prepareStatement(Connection conn,
|
||||||
|
SQLBuffer sql, JDBCFetchConfiguration fetch, int rsType,
|
||||||
|
int rsConcur, boolean isLRS) throws SQLException {
|
||||||
|
if (fetch == null)
|
||||||
|
return sql.prepareStatement(conn, rsType, rsConcur);
|
||||||
|
else
|
||||||
|
return sql.prepareStatement(conn, fetch, rsType, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
protected ResultSet executeQuery(Connection conn, PreparedStatement stmnt,
|
||||||
|
SQLBuffer sql, boolean isLRS, JDBCStore store) throws SQLException {
|
||||||
|
return stmnt.executeQuery();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of getting count from the result set.
|
||||||
|
*/
|
||||||
|
protected int getCount(ResultSet rs) throws SQLException {
|
||||||
|
rs.next();
|
||||||
|
return rs.getInt(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method is to provide override for non-JDBC or JDBC-like
|
||||||
|
* implementation of executing eager selects.
|
||||||
|
*/
|
||||||
|
protected Result getEagerResult(Connection conn,
|
||||||
|
PreparedStatement stmnt, ResultSet rs, JDBCStore store,
|
||||||
|
JDBCFetchConfiguration fetch, boolean forUpdate, String sqlStr)
|
||||||
|
throws SQLException {
|
||||||
|
SelectResult res = new SelectResult(conn, stmnt, rs, _dict);
|
||||||
|
res.setSelect(this);
|
||||||
|
res.setStore(store);
|
||||||
|
res.setLocking(forUpdate);
|
||||||
|
try {
|
||||||
|
addEagerResults(res, this, store, fetch);
|
||||||
|
} catch (SQLException se) {
|
||||||
|
res.close();
|
||||||
|
throw se;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
// Select implementation
|
// Select implementation
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
|
|
|
@ -39,7 +39,7 @@ import org.apache.openjpa.util.UserException;
|
||||||
*/
|
*/
|
||||||
public class Bootstrap {
|
public class Bootstrap {
|
||||||
|
|
||||||
private static final Class[] FACTORY_ARGS =
|
protected static final Class[] FACTORY_ARGS =
|
||||||
new Class[]{ ConfigurationProvider.class };
|
new Class[]{ ConfigurationProvider.class };
|
||||||
|
|
||||||
private static Localizer s_loc = Localizer.forPackage(Bootstrap.class);
|
private static Localizer s_loc = Localizer.forPackage(Bootstrap.class);
|
||||||
|
@ -124,7 +124,7 @@ public class Bootstrap {
|
||||||
return (BrokerFactory) meth.invoke(null, new Object[]{ conf });
|
return (BrokerFactory) meth.invoke(null, new Object[]{ conf });
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getFactoryClassName(ConfigurationProvider conf,
|
protected static String getFactoryClassName(ConfigurationProvider conf,
|
||||||
ClassLoader loader) {
|
ClassLoader loader) {
|
||||||
try {
|
try {
|
||||||
return getFactoryClass(conf, loader).getName();
|
return getFactoryClass(conf, loader).getName();
|
||||||
|
|
|
@ -2420,10 +2420,7 @@ public class BrokerImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure we don't already have the instance cached
|
// make sure we don't already have the instance cached
|
||||||
StateManagerImpl other = getStateManagerImplById(id, false);
|
checkForDuplicateId(id, obj);
|
||||||
if (other != null && !other.isDeleted() && !other.isNew())
|
|
||||||
throw new ObjectExistsException(_loc.get("cache-exists",
|
|
||||||
obj.getClass().getName(), id)).setFailedObject(obj);
|
|
||||||
|
|
||||||
// if had embedded sm, null it
|
// if had embedded sm, null it
|
||||||
if (sm != null)
|
if (sm != null)
|
||||||
|
@ -3817,7 +3814,7 @@ public class BrokerImpl
|
||||||
_cache.remove(id, sm);
|
_cache.remove(id, sm);
|
||||||
break;
|
break;
|
||||||
case STATUS_OID_ASSIGN:
|
case STATUS_OID_ASSIGN:
|
||||||
_cache.assignObjectId(id, sm);
|
assignObjectId(_cache, id, sm);
|
||||||
break;
|
break;
|
||||||
case STATUS_COMMIT_NEW:
|
case STATUS_COMMIT_NEW:
|
||||||
_cache.commitNew(id, sm);
|
_cache.commitNew(id, sm);
|
||||||
|
@ -4700,4 +4697,23 @@ public class BrokerImpl
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assign the object id to the cache. Exception will be
|
||||||
|
* thrown if the id already exists in the cache.
|
||||||
|
*/
|
||||||
|
protected void assignObjectId(Object cache, Object id,
|
||||||
|
StateManagerImpl sm) {
|
||||||
|
((ManagedCache) cache).assignObjectId(id, sm);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method makes sure we don't already have the instance cached
|
||||||
|
*/
|
||||||
|
protected void checkForDuplicateId(Object id, Object obj) {
|
||||||
|
StateManagerImpl other = getStateManagerImplById(id, false);
|
||||||
|
if (other != null && !other.isDeleted() && !other.isNew())
|
||||||
|
throw new ObjectExistsException(_loc.get("cache-exists",
|
||||||
|
obj.getClass().getName(), id)).setFailedObject(obj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3001,7 +3001,7 @@ public class StateManagerImpl
|
||||||
/**
|
/**
|
||||||
* Mark the field as loaded or unloaded.
|
* Mark the field as loaded or unloaded.
|
||||||
*/
|
*/
|
||||||
private void setLoaded(int field, boolean isLoaded) {
|
public void setLoaded(int field, boolean isLoaded) {
|
||||||
// don't continue if loaded state is already correct; otherwise we
|
// don't continue if loaded state is already correct; otherwise we
|
||||||
// can end up clearing _fieldImpl when we shouldn't
|
// can end up clearing _fieldImpl when we shouldn't
|
||||||
if (_loaded.get(field) == isLoaded)
|
if (_loaded.get(field) == isLoaded)
|
||||||
|
|
|
@ -22,8 +22,6 @@ import java.lang.instrument.ClassFileTransformer;
|
||||||
import java.lang.instrument.IllegalClassFormatException;
|
import java.lang.instrument.IllegalClassFormatException;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
import javax.persistence.EntityManager;
|
import javax.persistence.EntityManager;
|
||||||
import javax.persistence.spi.ClassTransformer;
|
import javax.persistence.spi.ClassTransformer;
|
||||||
import javax.persistence.spi.PersistenceProvider;
|
import javax.persistence.spi.PersistenceProvider;
|
||||||
|
@ -101,7 +99,7 @@ public class PersistenceProviderImpl
|
||||||
}
|
}
|
||||||
|
|
||||||
if (poolValue == null || !((Boolean) poolValue).booleanValue())
|
if (poolValue == null || !((Boolean) poolValue).booleanValue())
|
||||||
return Bootstrap.newBrokerFactory(cp, loader);
|
return newBrokerFactory(cp, loader);
|
||||||
else
|
else
|
||||||
return Bootstrap.getBrokerFactory(cp, loader);
|
return Bootstrap.getBrokerFactory(cp, loader);
|
||||||
}
|
}
|
||||||
|
@ -201,4 +199,19 @@ public class PersistenceProviderImpl
|
||||||
return _trans.transform(cl, name, previousVersion, pd, bytes);
|
return _trans.transform(cl, name, previousVersion, pd, bytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a persistence product deviration with default setting.
|
||||||
|
*/
|
||||||
|
public PersistenceProductDerivation newPersistenceProductDerivation() {
|
||||||
|
return new PersistenceProductDerivation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a broker factory for the given configuration and class loader.
|
||||||
|
*/
|
||||||
|
public BrokerFactory newBrokerFactory(ConfigurationProvider cp,
|
||||||
|
ClassLoader loader) {
|
||||||
|
return Bootstrap.newBrokerFactory(cp, loader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue