mirror of
https://github.com/apache/openjpa.git
synced 2025-02-08 11:06:01 +00:00
Framework for allowing ranges in query strings to be specified as parameters
(not needed for JPQL, but for others). Also consolidated some internal query framework APIs. git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@438338 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
47ead9315d
commit
163cc2a22c
@ -130,10 +130,10 @@ public class JDBCStoreQuery
|
|||||||
protected ResultObjectProvider executeQuery(Executor ex,
|
protected ResultObjectProvider executeQuery(Executor ex,
|
||||||
ClassMetaData base, ClassMetaData[] metas, boolean subclasses,
|
ClassMetaData base, ClassMetaData[] metas, boolean subclasses,
|
||||||
ExpressionFactory[] facts, QueryExpressions[] exps, Object[] params,
|
ExpressionFactory[] facts, QueryExpressions[] exps, Object[] params,
|
||||||
boolean lrs, long startIdx, long endIdx) {
|
Range range) {
|
||||||
if (metas.length > 1 && exps[0].isAggregate())
|
if (metas.length > 1 && exps[0].isAggregate())
|
||||||
throw new UserException(Localizer.forPackage(JDBCStoreQuery.class)
|
throw new UserException(Localizer.forPackage(JDBCStoreQuery.class).
|
||||||
.get("mult-mapping-aggregate", Arrays.asList(metas)));
|
get("mult-mapping-aggregate", Arrays.asList(metas)));
|
||||||
|
|
||||||
ClassMapping[] mappings = (ClassMapping[]) metas;
|
ClassMapping[] mappings = (ClassMapping[]) metas;
|
||||||
JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)
|
JDBCFetchConfiguration fetch = (JDBCFetchConfiguration)
|
||||||
@ -143,12 +143,12 @@ public class JDBCStoreQuery
|
|||||||
fetch.addJoins(Arrays.asList(exps[0].fetchPaths));
|
fetch.addJoins(Arrays.asList(exps[0].fetchPaths));
|
||||||
}
|
}
|
||||||
|
|
||||||
int eager = calculateEagerMode(exps[0], startIdx, endIdx);
|
int eager = calculateEagerMode(exps[0], range.start, range.end);
|
||||||
int subclassMode = fetch.getSubclassFetchMode((ClassMapping) base);
|
int subclassMode = fetch.getSubclassFetchMode((ClassMapping) base);
|
||||||
DBDictionary dict = _store.getDBDictionary();
|
DBDictionary dict = _store.getDBDictionary();
|
||||||
long start = (mappings.length == 1 && dict.supportsSelectStartIndex)
|
long start = (mappings.length == 1 && dict.supportsSelectStartIndex)
|
||||||
? startIdx : 0L;
|
? range.start : 0L;
|
||||||
long end = (dict.supportsSelectEndIndex) ? endIdx : Long.MAX_VALUE;
|
long end = (dict.supportsSelectEndIndex) ? range.end : Long.MAX_VALUE;
|
||||||
|
|
||||||
// add selects with populate WHERE conditions to list
|
// add selects with populate WHERE conditions to list
|
||||||
List sels = new ArrayList(mappings.length);
|
List sels = new ArrayList(mappings.length);
|
||||||
@ -165,8 +165,8 @@ public class JDBCStoreQuery
|
|||||||
// we might want to use lrs settings if we can't use the range
|
// we might want to use lrs settings if we can't use the range
|
||||||
if (sels.size() > 1)
|
if (sels.size() > 1)
|
||||||
start = 0L;
|
start = 0L;
|
||||||
lrs = lrs || (fetch.getFetchBatchSize() >= 0 && (start != startIdx
|
boolean lrs = range.lrs || (fetch.getFetchBatchSize() >= 0
|
||||||
|| end != endIdx));
|
&& (start != range.start || end != range.end));
|
||||||
|
|
||||||
ResultObjectProvider[] rops = null;
|
ResultObjectProvider[] rops = null;
|
||||||
ResultObjectProvider rop = null;
|
ResultObjectProvider rop = null;
|
||||||
@ -209,9 +209,9 @@ public class JDBCStoreQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
// need to fake result range?
|
// need to fake result range?
|
||||||
if ((rops != null && endIdx != Long.MAX_VALUE) || start != startIdx
|
if ((rops != null && range.end != Long.MAX_VALUE)
|
||||||
|| end != endIdx)
|
|| start != range.start || end != range.end)
|
||||||
rop = new RangeResultObjectProvider(rop, startIdx, endIdx);
|
rop = new RangeResultObjectProvider(rop, range.start, range.end);
|
||||||
return rop;
|
return rop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,7 +226,6 @@ public class JDBCStoreQuery
|
|||||||
final BitSet[] paged = (exps[0].projections.length > 0) ? null
|
final BitSet[] paged = (exps[0].projections.length > 0) ? null
|
||||||
: new BitSet[mappings.length];
|
: new BitSet[mappings.length];
|
||||||
union.select(new Union.Selector() {
|
union.select(new Union.Selector() {
|
||||||
|
|
||||||
public void select(Select sel, int idx) {
|
public void select(Select sel, int idx) {
|
||||||
BitSet bits = populateSelect(sel, mappings[idx], subclasses,
|
BitSet bits = populateSelect(sel, mappings[idx], subclasses,
|
||||||
(JDBCExpressionFactory) facts[idx], exps[idx], params,
|
(JDBCExpressionFactory) facts[idx], exps[idx], params,
|
||||||
@ -392,11 +391,11 @@ public class JDBCStoreQuery
|
|||||||
* or the query is unique, use an eager setting of single. Otherwise use
|
* or the query is unique, use an eager setting of single. Otherwise use
|
||||||
* an eager mode of multiple.
|
* an eager mode of multiple.
|
||||||
*/
|
*/
|
||||||
private int calculateEagerMode(QueryExpressions exps, long startIdx,
|
private int calculateEagerMode(QueryExpressions exps, long start,
|
||||||
long endIdx) {
|
long end) {
|
||||||
if (exps.projections.length > 0 || startIdx >= endIdx)
|
if (exps.projections.length > 0 || start >= end)
|
||||||
return EagerFetchModes.EAGER_NONE;
|
return EagerFetchModes.EAGER_NONE;
|
||||||
if (endIdx - startIdx == 1 || ctx.isUnique())
|
if (end - start == 1 || ctx.isUnique())
|
||||||
return EagerFetchModes.EAGER_JOIN;
|
return EagerFetchModes.EAGER_JOIN;
|
||||||
return EagerFetchModes.EAGER_PARALLEL;
|
return EagerFetchModes.EAGER_PARALLEL;
|
||||||
}
|
}
|
||||||
@ -479,19 +478,13 @@ public class JDBCStoreQuery
|
|||||||
count += stmnt.executeUpdate();
|
count += stmnt.executeUpdate();
|
||||||
} finally {
|
} finally {
|
||||||
if (stmnt != null)
|
if (stmnt != null)
|
||||||
try {
|
try { stmnt.close(); } catch (SQLException se) {}
|
||||||
stmnt.close();
|
|
||||||
} catch (SQLException se) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (SQLException se) {
|
} catch (SQLException se) {
|
||||||
throw SQLExceptions.getStore(se, ctx, _store.getDBDictionary());
|
throw SQLExceptions.getStore(se, ctx, _store.getDBDictionary());
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try { conn.close(); } catch (SQLException se) {}
|
||||||
conn.close();
|
|
||||||
} catch (SQLException se) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return Numbers.valueOf(count);
|
return Numbers.valueOf(count);
|
||||||
}
|
}
|
||||||
@ -572,22 +565,22 @@ public class JDBCStoreQuery
|
|||||||
|
|
||||||
protected String[] getDataStoreActions(ClassMetaData base,
|
protected String[] getDataStoreActions(ClassMetaData base,
|
||||||
ClassMetaData[] metas, boolean subclasses, ExpressionFactory[] facts,
|
ClassMetaData[] metas, boolean subclasses, ExpressionFactory[] facts,
|
||||||
QueryExpressions[] exps, Object[] params, long startIdx, long endIdx) {
|
QueryExpressions[] exps, Object[] params, Range range) {
|
||||||
ClassMapping[] mappings = (ClassMapping[]) metas;
|
ClassMapping[] mappings = (ClassMapping[]) metas;
|
||||||
JDBCFetchConfiguration fetch = (JDBCFetchConfiguration) ctx
|
JDBCFetchConfiguration fetch = (JDBCFetchConfiguration) ctx.
|
||||||
.getFetchConfiguration();
|
getFetchConfiguration();
|
||||||
if (exps[0].fetchPaths != null) {
|
if (exps[0].fetchPaths != null) {
|
||||||
fetch.addFields(Arrays.asList(exps[0].fetchPaths));
|
fetch.addFields(Arrays.asList(exps[0].fetchPaths));
|
||||||
fetch.addJoins(Arrays.asList(exps[0].fetchPaths));
|
fetch.addJoins(Arrays.asList(exps[0].fetchPaths));
|
||||||
}
|
}
|
||||||
|
|
||||||
int eager = calculateEagerMode(exps[0], startIdx, endIdx);
|
int eager = calculateEagerMode(exps[0], range.start, range.end);
|
||||||
eager = Math.min(eager, JDBCFetchConfiguration.EAGER_JOIN);
|
eager = Math.min(eager, JDBCFetchConfiguration.EAGER_JOIN);
|
||||||
int subclassMode = fetch.getSubclassFetchMode((ClassMapping) base);
|
int subclassMode = fetch.getSubclassFetchMode((ClassMapping) base);
|
||||||
DBDictionary dict = _store.getDBDictionary();
|
DBDictionary dict = _store.getDBDictionary();
|
||||||
long start = (mappings.length == 1 && dict.supportsSelectStartIndex)
|
long start = (mappings.length == 1 && dict.supportsSelectStartIndex)
|
||||||
? startIdx : 0L;
|
? range.start : 0L;
|
||||||
long end = (dict.supportsSelectEndIndex) ? endIdx : Long.MAX_VALUE;
|
long end = (dict.supportsSelectEndIndex) ? range.end : Long.MAX_VALUE;
|
||||||
|
|
||||||
// add selects with populate WHERE conditions to list
|
// add selects with populate WHERE conditions to list
|
||||||
List sels = new ArrayList(mappings.length);
|
List sels = new ArrayList(mappings.length);
|
||||||
|
@ -184,7 +184,7 @@ public class SQLStoreQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
public ResultObjectProvider executeQuery(StoreQuery q,
|
||||||
Object[] params, boolean lrs, long startIdx, long endIdx) {
|
Object[] params, Range range) {
|
||||||
JDBCStore store = ((SQLStoreQuery) q).getStore();
|
JDBCStore store = ((SQLStoreQuery) q).getStore();
|
||||||
DBDictionary dict = store.getDBDictionary();
|
DBDictionary dict = store.getDBDictionary();
|
||||||
String sql = q.getContext().getQueryString();
|
String sql = q.getContext().getQueryString();
|
||||||
@ -209,11 +209,11 @@ public class SQLStoreQuery
|
|||||||
PreparedStatement stmnt = null;
|
PreparedStatement stmnt = null;
|
||||||
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 && !lrs)
|
if (_select && !range.lrs)
|
||||||
stmnt = buf.prepareStatement(conn);
|
stmnt = buf.prepareStatement(conn);
|
||||||
else if (_select)
|
else if (_select)
|
||||||
stmnt = buf.prepareStatement(conn, fetch, -1, -1);
|
stmnt = buf.prepareStatement(conn, fetch, -1, -1);
|
||||||
else if (!lrs)
|
else if (!range.lrs)
|
||||||
stmnt = buf.prepareCall(conn);
|
stmnt = buf.prepareCall(conn);
|
||||||
else
|
else
|
||||||
stmnt = buf.prepareCall(conn, fetch, -1, -1);
|
stmnt = buf.prepareCall(conn, fetch, -1, -1);
|
||||||
@ -240,13 +240,13 @@ public class SQLStoreQuery
|
|||||||
throw SQLExceptions.getStore(se, dict);
|
throw SQLExceptions.getStore(se, dict);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startIdx != 0 || endIdx != Long.MAX_VALUE)
|
if (range.start != 0 || range.end != Long.MAX_VALUE)
|
||||||
rop = new RangeResultObjectProvider(rop, startIdx, endIdx);
|
rop = new RangeResultObjectProvider(rop, range.start,range.end);
|
||||||
return rop;
|
return rop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
||||||
long startIdx, long endIdx) {
|
Range range) {
|
||||||
return new String[]{ q.getContext().getQueryString() };
|
return new String[]{ q.getContext().getQueryString() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +48,6 @@ class SubQ
|
|||||||
private Class _type = null;
|
private Class _type = null;
|
||||||
private ClassMetaData _meta = null;
|
private ClassMetaData _meta = null;
|
||||||
private QueryExpressions _exps = null;
|
private QueryExpressions _exps = null;
|
||||||
private long _startIdx = 0;
|
|
||||||
private long _endIdx = Long.MAX_VALUE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor. Supply candidate, whether subclasses are included in
|
* Constructor. Supply candidate, whether subclasses are included in
|
||||||
@ -100,11 +98,8 @@ class SubQ
|
|||||||
return _alias;
|
return _alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setQueryExpressions(QueryExpressions query, long startIdx,
|
public void setQueryExpressions(QueryExpressions query) {
|
||||||
long endIdx) {
|
|
||||||
_exps = query;
|
_exps = query;
|
||||||
_startIdx = startIdx;
|
|
||||||
_endIdx = endIdx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(Select sel, JDBCStore store, boolean nullTest) {
|
public void initialize(Select sel, JDBCStore store, boolean nullTest) {
|
||||||
@ -180,7 +175,6 @@ class SubQ
|
|||||||
_cons.CACHE_NULL, fetch);
|
_cons.CACHE_NULL, fetch);
|
||||||
_cons.select(store, _candidate, _subs, sel, _exps, params,
|
_cons.select(store, _candidate, _subs, sel, _exps, params,
|
||||||
fetch, fetch.EAGER_NONE);
|
fetch, fetch.EAGER_NONE);
|
||||||
sel.setRange(_startIdx, _endIdx);
|
|
||||||
|
|
||||||
if (size)
|
if (size)
|
||||||
sql.appendCount(sel, fetch);
|
sql.appendCount(sel, fetch);
|
||||||
|
@ -22,7 +22,8 @@ update-failed-no-failed-obj: Database operation failed. Update count for SQL \
|
|||||||
virtual-mapping: Cannot instantiate virtual mapping "{0}".
|
virtual-mapping: Cannot instantiate virtual mapping "{0}".
|
||||||
press-key-end: Server running. Press enter to stop.
|
press-key-end: Server running. Press enter to stop.
|
||||||
no-server-conf: There is no persistence server configured.
|
no-server-conf: There is no persistence server configured.
|
||||||
server-usage: Usage: java org.apache.openjpa.jdbc.kernel.StartPersistenceServer\n\
|
server-usage: Usage: \
|
||||||
|
java org.apache.openjpa.jdbc.kernel.StartPersistenceServer\n\
|
||||||
\t[-properties/-p <properties file or resource>]\n\
|
\t[-properties/-p <properties file or resource>]\n\
|
||||||
\t[-<property name> <property value>]*
|
\t[-<property name> <property value>]*
|
||||||
cant-lock-on-load: The database is unable to lock this query. Each object \
|
cant-lock-on-load: The database is unable to lock this query. Each object \
|
||||||
@ -42,7 +43,7 @@ batch-not-supported: The update count for the statement was an invalid \
|
|||||||
value ({0}). This indicates that your database or JDBC driver does not \
|
value ({0}). This indicates that your database or JDBC driver does not \
|
||||||
have complete support for executing batch statements. Batch \
|
have complete support for executing batch statements. Batch \
|
||||||
functionality should be disabled by including "BatchLimit=0" in \
|
functionality should be disabled by including "BatchLimit=0" in \
|
||||||
your org.apache.openjpa.jdbc.DBDictionary configuration property. Statement: {1}
|
your openjpa.jdbc.DBDictionary configuration property. Statement: {1}
|
||||||
bad-synch-mappings: Invalid SynchronizeMappings operation ("{0}") specified. \
|
bad-synch-mappings: Invalid SynchronizeMappings operation ("{0}") specified. \
|
||||||
Valid operations are: {1}
|
Valid operations are: {1}
|
||||||
make-native-seq: Creating sequence.
|
make-native-seq: Creating sequence.
|
||||||
@ -59,7 +60,8 @@ bad-seq-type: This sequence of type "{0}" cannot generate values for \
|
|||||||
no-seq-sql: Error instantiating named sequence "{0}": Your database dictionary \
|
no-seq-sql: Error instantiating named sequence "{0}": Your database dictionary \
|
||||||
does not support native sequences. To tell the dictionary how to select \
|
does not support native sequences. To tell the dictionary how to select \
|
||||||
sequence values, use:\n\
|
sequence values, use:\n\
|
||||||
org.apache.openjpa.jdbc.DBDictionary: NextSequenceQuery="SELECT NEXT VALUE FOR \{0\}"\n\
|
openjpa.jdbc.DBDictionary: NextSequenceQuery="SELECT NEXT VALUE \
|
||||||
|
FOR \{0\}"\n\
|
||||||
Where the above string is replaced with the proper SQL for your database.
|
Where the above string is replaced with the proper SQL for your database.
|
||||||
invalid-seq-sql: No rows returned for sql "{0}". Check your configuration.
|
invalid-seq-sql: No rows returned for sql "{0}". Check your configuration.
|
||||||
insert-seq: Inserting row for this mapping into sequence table.
|
insert-seq: Inserting row for this mapping into sequence table.
|
||||||
@ -72,7 +74,8 @@ seq-usage: Usage: java org.apache.openjpa.jdbc.kernel.TableJDBCSeq\n\
|
|||||||
\t[-properties/-p <properties file or resource>]\n\
|
\t[-properties/-p <properties file or resource>]\n\
|
||||||
\t[-<property name> <property value>]*\n\
|
\t[-<property name> <property value>]*\n\
|
||||||
\t-action/-a <add | drop | get | set> [value]
|
\t-action/-a <add | drop | get | set> [value]
|
||||||
clstable-seq-usage: Usage: java org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq\n\
|
clstable-seq-usage: Usage: \
|
||||||
|
java org.apache.openjpa.jdbc.kernel.ClassTableJDBCSeq\n\
|
||||||
\t[-properties/-p <properties file or resource>]\n\
|
\t[-properties/-p <properties file or resource>]\n\
|
||||||
\t[-<property name> <property value>]*\n\
|
\t[-<property name> <property value>]*\n\
|
||||||
\t-action/-a <add | drop | get | set>\n\
|
\t-action/-a <add | drop | get | set>\n\
|
||||||
|
@ -0,0 +1,94 @@
|
|||||||
|
package org.apache.openjpa.ant;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||||
|
import org.apache.openjpa.conf.OpenJPAConfigurationImpl;
|
||||||
|
import org.apache.openjpa.enhance.ApplicationIdTool;
|
||||||
|
import org.apache.openjpa.lib.ant.AbstractTask;
|
||||||
|
import org.apache.openjpa.lib.conf.ConfigurationImpl;
|
||||||
|
import org.apache.openjpa.lib.util.CodeFormat;
|
||||||
|
import org.apache.openjpa.lib.util.Files;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>Executes the application id tool on the specified files. This task
|
||||||
|
* can take the following arguments:
|
||||||
|
* <ul>
|
||||||
|
* <li><code>directory</code></li>
|
||||||
|
* <li><code>ignoreErrors</code></li>
|
||||||
|
* <li><code>name</code></li>
|
||||||
|
* <li><code>suffix</code></li>
|
||||||
|
* <li><code>token</code></li>
|
||||||
|
* </ul>
|
||||||
|
* It can also take an embedded <code>codeFormat</code> element with attributes
|
||||||
|
* for the bean properties of the {@link CodeFormat}.</p>
|
||||||
|
*/
|
||||||
|
public class ApplicationIdToolTask
|
||||||
|
extends AbstractTask {
|
||||||
|
|
||||||
|
protected ApplicationIdTool.Flags flags = new ApplicationIdTool.Flags();
|
||||||
|
protected String dirName = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
public ApplicationIdToolTask() {
|
||||||
|
flags.format = new CodeFormat();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the output directory we want the enhancer to write to.
|
||||||
|
*/
|
||||||
|
public void setDirectory(String dirName) {
|
||||||
|
this.dirName = dirName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set whether to ignore errors.
|
||||||
|
*/
|
||||||
|
public void setIgnoreErrors(boolean ignoreErrors) {
|
||||||
|
flags.ignoreErrors = ignoreErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the name of the identity class; with this option you must supply
|
||||||
|
* exactly one class to run on.
|
||||||
|
*/
|
||||||
|
public void setName(String name) {
|
||||||
|
flags.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a suffix to append to persistent classes to form their identity
|
||||||
|
* class name.
|
||||||
|
*/
|
||||||
|
public void setSuffix(String suffix) {
|
||||||
|
flags.suffix = suffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the token to separate stringified primary key field values.
|
||||||
|
*/
|
||||||
|
public void setToken(String token) {
|
||||||
|
flags.token = token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create the embedded code format element.
|
||||||
|
*/
|
||||||
|
public Object createCodeFormat() {
|
||||||
|
return flags.format;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ConfigurationImpl newConfiguration() {
|
||||||
|
return new OpenJPAConfigurationImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void executeOn(String[] files)
|
||||||
|
throws IOException, ClassNotFoundException {
|
||||||
|
flags.directory = (dirName == null) ? null
|
||||||
|
: Files.getFile(dirName, getClassLoader());
|
||||||
|
ApplicationIdTool.run((OpenJPAConfiguration) getConfiguration(), files,
|
||||||
|
flags, getClassLoader ());
|
||||||
|
}
|
||||||
|
}
|
@ -293,30 +293,17 @@ public class QueryCacheStoreQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q, Object[] params,
|
public ResultObjectProvider executeQuery(StoreQuery q, Object[] params,
|
||||||
boolean lrs, long startIdx, long endIdx) {
|
Range range) {
|
||||||
QueryCacheStoreQuery cq = (QueryCacheStoreQuery) q;
|
QueryCacheStoreQuery cq = (QueryCacheStoreQuery) q;
|
||||||
QueryKey key = QueryKey.newInstance(cq.getContext(),
|
QueryKey key = QueryKey.newInstance(cq.getContext(),
|
||||||
_ex.isPacking(q), params, _candidate, _subs, startIdx, endIdx);
|
_ex.isPacking(q), params, _candidate, _subs, range.start,
|
||||||
|
range.end);
|
||||||
List cached = cq.checkCache(key);
|
List cached = cq.checkCache(key);
|
||||||
if (cached != null)
|
if (cached != null)
|
||||||
return new ListResultObjectProvider(cached);
|
return new ListResultObjectProvider(cached);
|
||||||
|
|
||||||
ResultObjectProvider rop = _ex.executeQuery(cq.getDelegate(),
|
ResultObjectProvider rop = _ex.executeQuery(cq.getDelegate(),
|
||||||
params, lrs, startIdx, endIdx);
|
params, range);
|
||||||
return cq.wrapResult(rop, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q, Map params,
|
|
||||||
boolean lrs, long startIdx, long endIdx) {
|
|
||||||
QueryCacheStoreQuery cq = (QueryCacheStoreQuery) q;
|
|
||||||
QueryKey key = QueryKey.newInstance(cq.getContext(),
|
|
||||||
_ex.isPacking(q), params, _candidate, _subs, startIdx, endIdx);
|
|
||||||
List cached = cq.checkCache(key);
|
|
||||||
if (cached != null)
|
|
||||||
return new ListResultObjectProvider(cached);
|
|
||||||
|
|
||||||
ResultObjectProvider rop = _ex.executeQuery(cq.getDelegate(),
|
|
||||||
params, lrs, startIdx, endIdx);
|
|
||||||
return cq.wrapResult(rop, key);
|
return cq.wrapResult(rop, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -351,14 +338,6 @@ public class QueryCacheStoreQuery
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeDelete(StoreQuery q, Map params) {
|
|
||||||
try {
|
|
||||||
return _ex.executeDelete(unwrap(q), params);
|
|
||||||
} finally {
|
|
||||||
clearAccesssPath(q);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number executeUpdate(StoreQuery q, Object[] params) {
|
public Number executeUpdate(StoreQuery q, Object[] params) {
|
||||||
try {
|
try {
|
||||||
return _ex.executeUpdate(unwrap(q), params);
|
return _ex.executeUpdate(unwrap(q), params);
|
||||||
@ -367,16 +346,8 @@ public class QueryCacheStoreQuery
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeUpdate(StoreQuery q, Map params) {
|
|
||||||
try {
|
|
||||||
return _ex.executeUpdate(unwrap(q), params);
|
|
||||||
} finally {
|
|
||||||
clearAccesssPath(q);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
||||||
long startIdx, long endIdx) {
|
Range range) {
|
||||||
return EMPTY_STRINGS;
|
return EMPTY_STRINGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,6 +355,10 @@ public class QueryCacheStoreQuery
|
|||||||
_ex.validate(unwrap(q));
|
_ex.validate(unwrap(q));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getRange(StoreQuery q, Object[] params, Range range) {
|
||||||
|
_ex.getRange(q, params, range);
|
||||||
|
}
|
||||||
|
|
||||||
public Object getOrderingValue(StoreQuery q, Object[] params,
|
public Object getOrderingValue(StoreQuery q, Object[] params,
|
||||||
Object resultObject, int orderIndex) {
|
Object resultObject, int orderIndex) {
|
||||||
return _ex.getOrderingValue(unwrap(q), params, resultObject,
|
return _ex.getOrderingValue(unwrap(q), params, resultObject,
|
||||||
|
@ -107,39 +107,25 @@ public abstract class AbstractStoreQuery
|
|||||||
public static abstract class AbstractExecutor
|
public static abstract class AbstractExecutor
|
||||||
implements Executor {
|
implements Executor {
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q, Map params,
|
|
||||||
boolean lrs, long startIdx, long endIdx) {
|
|
||||||
Object[] arr = q.getContext().toParameterArray
|
|
||||||
(q.getContext().getParameterTypes(), params);
|
|
||||||
return executeQuery(q, arr, lrs, startIdx, endIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number executeDelete(StoreQuery q, Object[] params) {
|
public Number executeDelete(StoreQuery q, Object[] params) {
|
||||||
return q.getContext().deleteInMemory(this, params);
|
return q.getContext().deleteInMemory(this, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeDelete(StoreQuery q, Map params) {
|
|
||||||
return executeDelete(q, q.getContext().toParameterArray
|
|
||||||
(q.getContext().getParameterTypes(), params));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number executeUpdate(StoreQuery q, Object[] params) {
|
public Number executeUpdate(StoreQuery q, Object[] params) {
|
||||||
return q.getContext().updateInMemory(this, params);
|
return q.getContext().updateInMemory(this, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeUpdate(StoreQuery q, Map params) {
|
|
||||||
return executeUpdate(q, q.getContext().toParameterArray
|
|
||||||
(q.getContext().getParameterTypes(), params));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
||||||
long startIdx, long endIdx) {
|
Range range) {
|
||||||
return EMPTY_STRINGS;
|
return EMPTY_STRINGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void validate(StoreQuery q) {
|
public void validate(StoreQuery q) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getRange(StoreQuery q, Object[] params, Range range) {
|
||||||
|
}
|
||||||
|
|
||||||
public Object getOrderingValue(StoreQuery q, Object[] params,
|
public Object getOrderingValue(StoreQuery q, Object[] params,
|
||||||
Object resultObject, int orderIndex) {
|
Object resultObject, int orderIndex) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -403,14 +403,6 @@ public class DelegatingQuery
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] toParameterArray(LinkedMap paramTypes, Map params) {
|
|
||||||
try {
|
|
||||||
return _query.toParameterArray(paramTypes, params);
|
|
||||||
} catch (RuntimeException re) {
|
|
||||||
throw translate(re);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number deleteInMemory(StoreQuery.Executor ex, Object[] params) {
|
public Number deleteInMemory(StoreQuery.Executor ex, Object[] params) {
|
||||||
try {
|
try {
|
||||||
return _query.deleteInMemory(ex, params);
|
return _query.deleteInMemory(ex, params);
|
||||||
|
@ -27,6 +27,7 @@ import org.apache.commons.collections.map.LinkedMap;
|
|||||||
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
import org.apache.openjpa.conf.OpenJPAConfiguration;
|
||||||
import org.apache.openjpa.kernel.exps.AbstractExpressionVisitor;
|
import org.apache.openjpa.kernel.exps.AbstractExpressionVisitor;
|
||||||
import org.apache.openjpa.kernel.exps.AggregateListener;
|
import org.apache.openjpa.kernel.exps.AggregateListener;
|
||||||
|
import org.apache.openjpa.kernel.exps.Constant;
|
||||||
import org.apache.openjpa.kernel.exps.ExpressionFactory;
|
import org.apache.openjpa.kernel.exps.ExpressionFactory;
|
||||||
import org.apache.openjpa.kernel.exps.ExpressionParser;
|
import org.apache.openjpa.kernel.exps.ExpressionParser;
|
||||||
import org.apache.openjpa.kernel.exps.FilterListener;
|
import org.apache.openjpa.kernel.exps.FilterListener;
|
||||||
@ -177,18 +178,13 @@ public class ExpressionStoreQuery
|
|||||||
* each base type
|
* each base type
|
||||||
* @param parsed the parsed query values
|
* @param parsed the parsed query values
|
||||||
* @param params parameter values, or empty array
|
* @param params parameter values, or empty array
|
||||||
* @param lrs whether the result will be handled as a potentially
|
* @param range result range
|
||||||
* large result set, or will be consumed greedily
|
|
||||||
* @param startIdx 0-based inclusive index for first result to return
|
|
||||||
* from result object provider
|
|
||||||
* @param endIdx 0-based exclusive index for last result to return
|
|
||||||
* from result object provider, or {@link Long#MAX_VALUE} for no max
|
|
||||||
* @return a provider for matching objects
|
* @return a provider for matching objects
|
||||||
*/
|
*/
|
||||||
protected ResultObjectProvider executeQuery(Executor ex,
|
protected ResultObjectProvider executeQuery(Executor ex,
|
||||||
ClassMetaData base, ClassMetaData[] types, boolean subclasses,
|
ClassMetaData base, ClassMetaData[] types, boolean subclasses,
|
||||||
ExpressionFactory[] facts, QueryExpressions[] parsed, Object[] params,
|
ExpressionFactory[] facts, QueryExpressions[] parsed, Object[] params,
|
||||||
boolean lrs, long startIdx, long endIdx) {
|
Range range) {
|
||||||
throw new UnsupportedException();
|
throw new UnsupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -246,16 +242,12 @@ public class ExpressionStoreQuery
|
|||||||
* each base type
|
* each base type
|
||||||
* @param parsed the parsed query values
|
* @param parsed the parsed query values
|
||||||
* @param params parameter values, or empty array
|
* @param params parameter values, or empty array
|
||||||
* @param startIdx 0-based inclusive index for first result to return
|
* @param range result range
|
||||||
* from result object provider
|
|
||||||
* @param endIdx 0-based exclusive index for last result to return
|
|
||||||
* from result object provider, or {@link Long#MAX_VALUE} for no max
|
|
||||||
* @return a textual description of the query to execute
|
* @return a textual description of the query to execute
|
||||||
*/
|
*/
|
||||||
protected String[] getDataStoreActions(Executor ex, ClassMetaData base,
|
protected String[] getDataStoreActions(Executor ex, ClassMetaData base,
|
||||||
ClassMetaData[] types, boolean subclasses, ExpressionFactory[] facts,
|
ClassMetaData[] types, boolean subclasses, ExpressionFactory[] facts,
|
||||||
QueryExpressions[] parsed, Object[] params, long startIdx,
|
QueryExpressions[] parsed, Object[] params, Range range) {
|
||||||
long endIdx) {
|
|
||||||
return StoreQuery.EMPTY_STRINGS;
|
return StoreQuery.EMPTY_STRINGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,6 +320,30 @@ public class ExpressionStoreQuery
|
|||||||
ValidateGroupingExpressionVisitor.validate(q.getContext(), exps);
|
ValidateGroupingExpressionVisitor.validate(q.getContext(), exps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getRange(StoreQuery q, Object[] params, Range range) {
|
||||||
|
QueryExpressions exps = assertQueryExpression();
|
||||||
|
if (exps.range.length == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (exps.range.length == 2
|
||||||
|
&& exps.range[0] instanceof Constant
|
||||||
|
&& exps.range[1] instanceof Constant) {
|
||||||
|
try {
|
||||||
|
range.start = ((Number) ((Constant) exps.range[0]).
|
||||||
|
getValue(params)).longValue();
|
||||||
|
range.end = ((Number) ((Constant) exps.range[1]).
|
||||||
|
getValue(params)).longValue();
|
||||||
|
return;
|
||||||
|
} catch (ClassCastException cce) {
|
||||||
|
// fall through to exception below
|
||||||
|
} catch (NullPointerException npe) {
|
||||||
|
// fall through to exception below
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new UserException(_loc.get("only-range-constants",
|
||||||
|
q.getContext().getQueryString()));
|
||||||
|
}
|
||||||
|
|
||||||
public final Class getResultClass(StoreQuery q) {
|
public final Class getResultClass(StoreQuery q) {
|
||||||
return assertQueryExpression().resultClass;
|
return assertQueryExpression().resultClass;
|
||||||
}
|
}
|
||||||
@ -488,7 +504,7 @@ public class ExpressionStoreQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
public ResultObjectProvider executeQuery(StoreQuery q,
|
||||||
Object[] params, boolean lrs, long startIdx, long endIdx) {
|
Object[] params, Range range) {
|
||||||
// execute in memory for candidate collection;
|
// execute in memory for candidate collection;
|
||||||
// also execute in memory for transactional extents
|
// also execute in memory for transactional extents
|
||||||
Collection coll = q.getContext().getCandidateCollection();
|
Collection coll = q.getContext().getCandidateCollection();
|
||||||
@ -539,19 +555,13 @@ public class ExpressionStoreQuery
|
|||||||
results = _factory.distinct(_exps[0], coll == null, results);
|
results = _factory.distinct(_exps[0], coll == null, results);
|
||||||
|
|
||||||
ResultObjectProvider rop = new ListResultObjectProvider(results);
|
ResultObjectProvider rop = new ListResultObjectProvider(results);
|
||||||
if (startIdx != 0 || endIdx != Long.MAX_VALUE)
|
if (range.start != 0 || range.end != Long.MAX_VALUE)
|
||||||
rop = new RangeResultObjectProvider(rop, startIdx, endIdx);
|
rop = new RangeResultObjectProvider(rop, range.start,range.end);
|
||||||
return rop;
|
return rop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
|
||||||
Map params, boolean lrs, long startIdx, long endIdx) {
|
|
||||||
return executeQuery(q, q.getContext().toParameterArray
|
|
||||||
(getParameterTypes(q), params), lrs, startIdx, endIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
||||||
long startIdx, long endIdx) {
|
Range range) {
|
||||||
// in memory queries have no datastore actions to perform
|
// in memory queries have no datastore actions to perform
|
||||||
return StoreQuery.EMPTY_STRINGS;
|
return StoreQuery.EMPTY_STRINGS;
|
||||||
}
|
}
|
||||||
@ -646,16 +656,10 @@ public class ExpressionStoreQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
public ResultObjectProvider executeQuery(StoreQuery q,
|
||||||
Object[] params, boolean lrs, long startIdx, long endIdx) {
|
Object[] params, Range range) {
|
||||||
lrs = lrs && !isAggregate(q) && !hasGrouping(q);
|
range.lrs &= !isAggregate(q) && !hasGrouping(q);
|
||||||
return ((ExpressionStoreQuery) q).executeQuery(this, _meta, _metas,
|
return ((ExpressionStoreQuery) q).executeQuery(this, _meta, _metas,
|
||||||
_subs, _facts, _exps, params, lrs, startIdx, endIdx);
|
_subs, _facts, _exps, params, range);
|
||||||
}
|
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
|
||||||
Map params, boolean lrs, long startIdx, long endIdx) {
|
|
||||||
return executeQuery(q, q.getContext().toParameterArray
|
|
||||||
(getParameterTypes(q), params), lrs, startIdx, endIdx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeDelete(StoreQuery q, Object[] params) {
|
public Number executeDelete(StoreQuery q, Object[] params) {
|
||||||
@ -666,11 +670,6 @@ public class ExpressionStoreQuery
|
|||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeDelete(StoreQuery q, Map params) {
|
|
||||||
return executeDelete(q, q.getContext().toParameterArray
|
|
||||||
(getParameterTypes(q), params));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number executeUpdate(StoreQuery q, Object[] params) {
|
public Number executeUpdate(StoreQuery q, Object[] params) {
|
||||||
Number num = ((ExpressionStoreQuery) q).executeUpdate(this, _meta,
|
Number num = ((ExpressionStoreQuery) q).executeUpdate(this, _meta,
|
||||||
_metas, _subs, _facts, _exps, params);
|
_metas, _subs, _facts, _exps, params);
|
||||||
@ -679,15 +678,10 @@ public class ExpressionStoreQuery
|
|||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeUpdate(StoreQuery q, Map params) {
|
|
||||||
return executeUpdate(q, q.getContext().toParameterArray
|
|
||||||
(getParameterTypes(q), params));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
||||||
long startIdx, long endIdx) {
|
Range range) {
|
||||||
return ((ExpressionStoreQuery) q).getDataStoreActions(this, _meta,
|
return ((ExpressionStoreQuery) q).getDataStoreActions(this, _meta,
|
||||||
_metas, _subs, _facts, _exps, params, startIdx, endIdx);
|
_metas, _subs, _facts, _exps, params, range);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object getOrderingValue(StoreQuery q, Object[] params,
|
public Object getOrderingValue(StoreQuery q, Object[] params,
|
||||||
|
@ -135,7 +135,7 @@ public class MethodStoreQuery
|
|||||||
}
|
}
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
public ResultObjectProvider executeQuery(StoreQuery q,
|
||||||
Object[] params, boolean lrs, long startIdx, long endIdx) {
|
Object[] params, Range range) {
|
||||||
// convert the parameters into a map
|
// convert the parameters into a map
|
||||||
Map paramMap;
|
Map paramMap;
|
||||||
if (params.length == 0)
|
if (params.length == 0)
|
||||||
@ -148,19 +148,14 @@ public class MethodStoreQuery
|
|||||||
itr.hasNext(); idx++)
|
itr.hasNext(); idx++)
|
||||||
paramMap.put(itr.next(), params[idx]);
|
paramMap.put(itr.next(), params[idx]);
|
||||||
}
|
}
|
||||||
return executeQuery(q, paramMap, lrs, startIdx, endIdx);
|
|
||||||
}
|
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
|
||||||
Map params, boolean lrs, long startIdx, long endIdx) {
|
|
||||||
FetchConfiguration fetch = q.getContext().getFetchConfiguration();
|
FetchConfiguration fetch = q.getContext().getFetchConfiguration();
|
||||||
StoreContext sctx = q.getContext().getStoreContext();
|
StoreContext sctx = q.getContext().getStoreContext();
|
||||||
|
|
||||||
ResultObjectProvider rop;
|
ResultObjectProvider rop;
|
||||||
Object[] args;
|
Object[] args;
|
||||||
if (_inMem) {
|
if (_inMem) {
|
||||||
args = new Object[]{ sctx, _meta, (_subs) ? Boolean.TRUE
|
args = new Object[]{ sctx, _meta, (_subs) ? Boolean.TRUE
|
||||||
: Boolean.FALSE, null, params, fetch };
|
: Boolean.FALSE, null, paramMap, fetch };
|
||||||
|
|
||||||
Iterator itr = null;
|
Iterator itr = null;
|
||||||
Collection coll = q.getContext().getCandidateCollection();
|
Collection coll = q.getContext().getCandidateCollection();
|
||||||
@ -192,12 +187,12 @@ public class MethodStoreQuery
|
|||||||
} else {
|
} else {
|
||||||
// datastore
|
// datastore
|
||||||
args = new Object[]{ sctx, _meta, (_subs) ? Boolean.TRUE
|
args = new Object[]{ sctx, _meta, (_subs) ? Boolean.TRUE
|
||||||
: Boolean.FALSE, params, fetch };
|
: Boolean.FALSE, paramMap, fetch };
|
||||||
rop = (ResultObjectProvider) invoke(q, args);
|
rop = (ResultObjectProvider) invoke(q, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startIdx != 0 || endIdx != Long.MAX_VALUE)
|
if (range.start != 0 || range.end != Long.MAX_VALUE)
|
||||||
rop = new RangeResultObjectProvider(rop, startIdx, endIdx);
|
rop = new RangeResultObjectProvider(rop, range.start,range.end);
|
||||||
return rop;
|
return rop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,11 +248,6 @@ public interface QueryContext {
|
|||||||
*/
|
*/
|
||||||
public Collection getAggregateListeners();
|
public Collection getAggregateListeners();
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper method to transform the given parameters into an array.
|
|
||||||
*/
|
|
||||||
public Object[] toParameterArray(LinkedMap paramTypes, Map params);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to delete the objects found by executing a query on
|
* Helper method to delete the objects found by executing a query on
|
||||||
* the given executor.
|
* the given executor.
|
||||||
|
@ -104,6 +104,7 @@ public class QueryImpl
|
|||||||
private Class _resultClass = null;
|
private Class _resultClass = null;
|
||||||
private transient long _startIdx = 0;
|
private transient long _startIdx = 0;
|
||||||
private transient long _endIdx = Long.MAX_VALUE;
|
private transient long _endIdx = Long.MAX_VALUE;
|
||||||
|
private transient boolean _rangeSet = false;
|
||||||
|
|
||||||
// remember the list of all the results we have returned so we
|
// remember the list of all the results we have returned so we
|
||||||
// can free their resources when close or closeAll is called
|
// can free their resources when close or closeAll is called
|
||||||
@ -486,35 +487,13 @@ public class QueryImpl
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long getStartRange() {
|
public long getStartRange() {
|
||||||
lock();
|
|
||||||
try {
|
|
||||||
assertOpen();
|
assertOpen();
|
||||||
if (_startIdx != 0 || _endIdx != Long.MAX_VALUE
|
|
||||||
|| _compiled != null || _query == null || _broker == null)
|
|
||||||
return _startIdx;
|
return _startIdx;
|
||||||
|
|
||||||
// check again after compilation; maybe encoded in string
|
|
||||||
compileForCompilation();
|
|
||||||
return _startIdx;
|
|
||||||
} finally {
|
|
||||||
unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getEndRange() {
|
public long getEndRange() {
|
||||||
lock();
|
|
||||||
try {
|
|
||||||
assertOpen();
|
assertOpen();
|
||||||
if (_startIdx != 0 || _endIdx != Long.MAX_VALUE
|
|
||||||
|| _compiled != null || _query == null || _broker == null)
|
|
||||||
return _endIdx;
|
return _endIdx;
|
||||||
|
|
||||||
// check again after compilation; maybe encoded in string
|
|
||||||
compileForCompilation();
|
|
||||||
return _endIdx;
|
|
||||||
} finally {
|
|
||||||
unlock();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRange(long start, long end) {
|
public void setRange(long start, long end) {
|
||||||
@ -532,6 +511,7 @@ public class QueryImpl
|
|||||||
// allowed modification: no read-only check
|
// allowed modification: no read-only check
|
||||||
_startIdx = start;
|
_startIdx = start;
|
||||||
_endIdx = end;
|
_endIdx = end;
|
||||||
|
_rangeSet = true;
|
||||||
} finally {
|
} finally {
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
@ -703,7 +683,7 @@ public class QueryImpl
|
|||||||
else
|
else
|
||||||
es[i] = _storeQuery.newDataStoreExecutor(metas[i], true);
|
es[i] = _storeQuery.newDataStoreExecutor(metas[i], true);
|
||||||
}
|
}
|
||||||
return new MergedExecutor(es, this);
|
return new MergedExecutor(es);
|
||||||
} catch (OpenJPAException ke) {
|
} catch (OpenJPAException ke) {
|
||||||
throw ke;
|
throw ke;
|
||||||
} catch (RuntimeException re) {
|
} catch (RuntimeException re) {
|
||||||
@ -799,16 +779,18 @@ public class QueryImpl
|
|||||||
StoreQuery.Executor ex = (isInMemory(operation))
|
StoreQuery.Executor ex = (isInMemory(operation))
|
||||||
? compileForInMemory(comp) : compileForDataStore(comp);
|
? compileForInMemory(comp) : compileForDataStore(comp);
|
||||||
|
|
||||||
assertParameters(ex, params);
|
Object[] arr = (params.isEmpty()) ? StoreQuery.EMPTY_OBJECTS :
|
||||||
|
toParameterArray(ex.getParameterTypes(_storeQuery), params);
|
||||||
|
assertParameters(ex, arr);
|
||||||
if (_log.isTraceEnabled())
|
if (_log.isTraceEnabled())
|
||||||
logExecution(operation, params);
|
logExecution(operation, params);
|
||||||
|
|
||||||
if (operation == OP_SELECT)
|
if (operation == OP_SELECT)
|
||||||
return execute(ex, params);
|
return execute(ex, arr);
|
||||||
if (operation == OP_DELETE)
|
if (operation == OP_DELETE)
|
||||||
return delete(ex, params);
|
return delete(ex, arr);
|
||||||
if (operation == OP_UPDATE)
|
if (operation == OP_UPDATE)
|
||||||
return update(ex, params);
|
return update(ex, arr);
|
||||||
throw new UnsupportedException();
|
throw new UnsupportedException();
|
||||||
} catch (OpenJPAException ke) {
|
} catch (OpenJPAException ke) {
|
||||||
throw ke;
|
throw ke;
|
||||||
@ -847,7 +829,7 @@ public class QueryImpl
|
|||||||
return ((Number) execute(OP_UPDATE, params)).longValue();
|
return ((Number) execute(OP_UPDATE, params)).longValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Object[] toParameterArray(LinkedMap paramTypes, Map params) {
|
private Object[] toParameterArray(LinkedMap paramTypes, Map params) {
|
||||||
if (params == null || params.isEmpty())
|
if (params == null || params.isEmpty())
|
||||||
return StoreQuery.EMPTY_OBJECTS;
|
return StoreQuery.EMPTY_OBJECTS;
|
||||||
|
|
||||||
@ -940,16 +922,18 @@ public class QueryImpl
|
|||||||
private Object execute(StoreQuery.Executor ex, Object[] params)
|
private Object execute(StoreQuery.Executor ex, Object[] params)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
// if this is an impossible result range, return null / empty list
|
// if this is an impossible result range, return null / empty list
|
||||||
if (_startIdx >= _endIdx)
|
StoreQuery.Range range = new StoreQuery.Range(_startIdx, _endIdx);
|
||||||
|
if (!_rangeSet)
|
||||||
|
ex.getRange(_storeQuery, params, range);
|
||||||
|
if (range.start >= range.end)
|
||||||
return emptyResult(ex);
|
return emptyResult(ex);
|
||||||
|
|
||||||
// execute; if we have a result class or we have only one result
|
// execute; if we have a result class or we have only one result
|
||||||
// and so need to remove it from its array, wrap in a packing rop
|
// and so need to remove it from its array, wrap in a packing rop
|
||||||
boolean lrs = isLRS();
|
range.lrs = isLRS(range.start, range.end);
|
||||||
ResultObjectProvider rop = ex.executeQuery(_storeQuery, params, lrs,
|
ResultObjectProvider rop = ex.executeQuery(_storeQuery, params, range);
|
||||||
_startIdx, _endIdx);
|
|
||||||
try {
|
try {
|
||||||
return toResult(ex, rop, lrs);
|
return toResult(ex, rop, range);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (rop != null)
|
if (rop != null)
|
||||||
try { rop.close(); } catch (Exception e2) {}
|
try { rop.close(); } catch (Exception e2) {}
|
||||||
@ -957,48 +941,6 @@ public class QueryImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the query using the given compilation, executor, and parameter
|
|
||||||
* values. All other execute methods delegate to this one or to
|
|
||||||
* {@link #execute(StoreQuery.Executor,Object[])} after validation and
|
|
||||||
* locking.
|
|
||||||
*/
|
|
||||||
private Object execute(StoreQuery.Executor ex, Map params)
|
|
||||||
throws Exception {
|
|
||||||
// if this is an impossible result range, return null / empty list
|
|
||||||
if (_startIdx >= _endIdx)
|
|
||||||
return emptyResult(ex);
|
|
||||||
|
|
||||||
// execute; if we have a result class or we have only one result
|
|
||||||
// and so need to remove it from its array, wrap in a packing rop
|
|
||||||
boolean lrs = isLRS();
|
|
||||||
ResultObjectProvider rop = ex.executeQuery(_storeQuery, params, lrs,
|
|
||||||
_startIdx, _endIdx);
|
|
||||||
try {
|
|
||||||
return toResult(ex, rop, lrs);
|
|
||||||
} catch (Exception e) {
|
|
||||||
if (rop != null)
|
|
||||||
try {
|
|
||||||
rop.close();
|
|
||||||
} catch (Exception e2) {
|
|
||||||
}
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the query using the given executor, and parameter
|
|
||||||
* values. All other execute methods delegate to this one or to
|
|
||||||
* {@link #delete(StoreQuery.Executor,Object[])} after validation and
|
|
||||||
* locking. The return value will be a Number indicating the number of
|
|
||||||
* instances deleted.
|
|
||||||
*/
|
|
||||||
private Number delete(StoreQuery.Executor ex, Map params)
|
|
||||||
throws Exception {
|
|
||||||
assertBulkModify();
|
|
||||||
return ex.executeDelete(_storeQuery, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the query using the given executor, and parameter
|
* Delete the query using the given executor, and parameter
|
||||||
* values. All other execute methods delegate to this one or to
|
* values. All other execute methods delegate to this one or to
|
||||||
@ -1008,7 +950,7 @@ public class QueryImpl
|
|||||||
*/
|
*/
|
||||||
private Number delete(StoreQuery.Executor ex, Object[] params)
|
private Number delete(StoreQuery.Executor ex, Object[] params)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
assertBulkModify();
|
assertBulkModify(ex, params);
|
||||||
return ex.executeDelete(_storeQuery, params);
|
return ex.executeDelete(_storeQuery, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1030,19 +972,6 @@ public class QueryImpl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the query using the given executor and parameter
|
|
||||||
* values. All other execute methods delegate to this one or to
|
|
||||||
* {@link #update(StoreQuery.Executor,Object[])} after validation and
|
|
||||||
* locking. The return value will be a Number indicating the number of
|
|
||||||
* instances updated.
|
|
||||||
*/
|
|
||||||
private Number update(StoreQuery.Executor ex, Map params)
|
|
||||||
throws Exception {
|
|
||||||
assertBulkModify();
|
|
||||||
return ex.executeUpdate(_storeQuery, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the query using the given compilation, executor, and parameter
|
* Update the query using the given compilation, executor, and parameter
|
||||||
* values. All other execute methods delegate to this one or to
|
* values. All other execute methods delegate to this one or to
|
||||||
@ -1052,7 +981,7 @@ public class QueryImpl
|
|||||||
*/
|
*/
|
||||||
private Number update(StoreQuery.Executor ex, Object[] params)
|
private Number update(StoreQuery.Executor ex, Object[] params)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
assertBulkModify();
|
assertBulkModify(ex, params);
|
||||||
return ex.executeUpdate(_storeQuery, params);
|
return ex.executeUpdate(_storeQuery, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,7 +1015,7 @@ public class QueryImpl
|
|||||||
Map.Entry e = (Map.Entry) it.next();
|
Map.Entry e = (Map.Entry) it.next();
|
||||||
FieldMetaData fmd = (FieldMetaData) e.getKey();
|
FieldMetaData fmd = (FieldMetaData) e.getKey();
|
||||||
if (!(e.getValue() instanceof Constant))
|
if (!(e.getValue() instanceof Constant))
|
||||||
throw new UserException(_loc.get("only-update-primitives"));
|
throw new UserException(_loc.get("only-update-constants"));
|
||||||
Constant value = (Constant) e.getValue();
|
Constant value = (Constant) e.getValue();
|
||||||
Object val = value.getValue(params);
|
Object val = value.getValue(params);
|
||||||
|
|
||||||
@ -1195,8 +1124,8 @@ public class QueryImpl
|
|||||||
/**
|
/**
|
||||||
* Return whether this should be treated as a potential large result set.
|
* Return whether this should be treated as a potential large result set.
|
||||||
*/
|
*/
|
||||||
private boolean isLRS() {
|
private boolean isLRS(long start, long end) {
|
||||||
long range = _endIdx - _startIdx;
|
long range = end - start;
|
||||||
return _fc.getFetchBatchSize() >= 0
|
return _fc.getFetchBatchSize() >= 0
|
||||||
&& !(range <= _fc.getFetchBatchSize()
|
&& !(range <= _fc.getFetchBatchSize()
|
||||||
|| (_fc.getFetchBatchSize() == 0 && range <= 50));
|
|| (_fc.getFetchBatchSize() == 0 && range <= 50));
|
||||||
@ -1206,7 +1135,7 @@ public class QueryImpl
|
|||||||
* Return the query result for the given result object provider.
|
* Return the query result for the given result object provider.
|
||||||
*/
|
*/
|
||||||
protected Object toResult(StoreQuery.Executor ex, ResultObjectProvider rop,
|
protected Object toResult(StoreQuery.Executor ex, ResultObjectProvider rop,
|
||||||
boolean lrs)
|
StoreQuery.Range range)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
// pack projections if necessary
|
// pack projections if necessary
|
||||||
String[] aliases = ex.getProjectionAliases(_storeQuery);
|
String[] aliases = ex.getProjectionAliases(_storeQuery);
|
||||||
@ -1220,13 +1149,13 @@ public class QueryImpl
|
|||||||
// if single result, extract it
|
// if single result, extract it
|
||||||
if (_unique == Boolean.TRUE || (aliases.length > 0
|
if (_unique == Boolean.TRUE || (aliases.length > 0
|
||||||
&& !ex.hasGrouping(_storeQuery) && ex.isAggregate(_storeQuery)))
|
&& !ex.hasGrouping(_storeQuery) && ex.isAggregate(_storeQuery)))
|
||||||
return singleResult(rop);
|
return singleResult(rop, range);
|
||||||
|
|
||||||
// now that we've executed the query, we can call isAggregate and
|
// now that we've executed the query, we can call isAggregate and
|
||||||
// hasGrouping efficiently
|
// hasGrouping efficiently
|
||||||
boolean detach = (_broker.getAutoDetach() &
|
boolean detach = (_broker.getAutoDetach() &
|
||||||
AutoDetach.DETACH_NONTXREAD) > 0 && !_broker.isActive();
|
AutoDetach.DETACH_NONTXREAD) > 0 && !_broker.isActive();
|
||||||
lrs = lrs && !ex.isAggregate(_storeQuery)
|
boolean lrs = range.lrs && !ex.isAggregate(_storeQuery)
|
||||||
&& !ex.hasGrouping(_storeQuery);
|
&& !ex.hasGrouping(_storeQuery);
|
||||||
ResultList res = (!detach && lrs) ? _fc.newResultList(rop)
|
ResultList res = (!detach && lrs) ? _fc.newResultList(rop)
|
||||||
: new EagerResultList(rop);
|
: new EagerResultList(rop);
|
||||||
@ -1281,7 +1210,8 @@ public class QueryImpl
|
|||||||
* Extract an expected single result from the given provider. Used when
|
* Extract an expected single result from the given provider. Used when
|
||||||
* the result is an ungrouped aggregate or the unique flag is set to true.
|
* the result is an ungrouped aggregate or the unique flag is set to true.
|
||||||
*/
|
*/
|
||||||
private Object singleResult(ResultObjectProvider rop)
|
private Object singleResult(ResultObjectProvider rop,
|
||||||
|
StoreQuery.Range range)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
rop.open();
|
rop.open();
|
||||||
try {
|
try {
|
||||||
@ -1293,7 +1223,7 @@ public class QueryImpl
|
|||||||
Object single = null;
|
Object single = null;
|
||||||
if (next) {
|
if (next) {
|
||||||
single = rop.getResultObject();
|
single = rop.getResultObject();
|
||||||
if (_endIdx != _startIdx + 1 && rop.next())
|
if (range.end != range.start + 1 && rop.next())
|
||||||
throw new InvalidStateException(_loc.get("not-unique",
|
throw new InvalidStateException(_loc.get("not-unique",
|
||||||
_class, _query));
|
_class, _query));
|
||||||
}
|
}
|
||||||
@ -1397,10 +1327,13 @@ public class QueryImpl
|
|||||||
assertOpen();
|
assertOpen();
|
||||||
|
|
||||||
StoreQuery.Executor ex = compileForExecutor();
|
StoreQuery.Executor ex = compileForExecutor();
|
||||||
assertParameters(ex, params);
|
|
||||||
Object[] arr = toParameterArray(ex.getParameterTypes(_storeQuery),
|
Object[] arr = toParameterArray(ex.getParameterTypes(_storeQuery),
|
||||||
params);
|
params);
|
||||||
return ex.getDataStoreActions(_storeQuery, arr, _startIdx, _endIdx);
|
assertParameters(ex, arr);
|
||||||
|
StoreQuery.Range range = new StoreQuery.Range(_startIdx, _endIdx);
|
||||||
|
if (!_rangeSet)
|
||||||
|
ex.getRange(_storeQuery, arr, range);
|
||||||
|
return ex.getDataStoreActions(_storeQuery, arr, range);
|
||||||
} catch (OpenJPAException ke) {
|
} catch (OpenJPAException ke) {
|
||||||
throw ke;
|
throw ke;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -1654,44 +1587,16 @@ public class QueryImpl
|
|||||||
* Check that we are in a state to be able to perform a bulk operation;
|
* Check that we are in a state to be able to perform a bulk operation;
|
||||||
* also flush the current modfications if any elements are currently dirty.
|
* also flush the current modfications if any elements are currently dirty.
|
||||||
*/
|
*/
|
||||||
private void assertBulkModify() {
|
private void assertBulkModify(StoreQuery.Executor ex, Object[] params) {
|
||||||
_broker.assertActiveTransaction();
|
_broker.assertActiveTransaction();
|
||||||
if (_startIdx != 0 || _endIdx != Long.MAX_VALUE)
|
if (_startIdx != 0 || _endIdx != Long.MAX_VALUE)
|
||||||
throw new UserException(_loc.get("no-modify-range"));
|
throw new UserException(_loc.get("no-modify-range"));
|
||||||
if (_resultClass != null)
|
if (_resultClass != null)
|
||||||
throw new UserException(_loc.get("no-modify-resultclass"));
|
throw new UserException(_loc.get("no-modify-resultclass"));
|
||||||
}
|
StoreQuery.Range range = new StoreQuery.Range();
|
||||||
|
ex.getRange(_storeQuery, params, range);
|
||||||
/**
|
if (range.start != 0 || range.end != Long.MAX_VALUE)
|
||||||
* Checks that the passed parameters match the declarations.
|
throw new UserException(_loc.get("no-modify-range"));
|
||||||
*/
|
|
||||||
private void assertParameters(StoreQuery.Executor ex, Map params) {
|
|
||||||
if (!_storeQuery.requiresParameterDeclarations())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// check that all declared parameters are given compatible values
|
|
||||||
LinkedMap paramTypes = ex.getParameterTypes(_storeQuery);
|
|
||||||
if (paramTypes != null && !paramTypes.isEmpty()) {
|
|
||||||
Map.Entry entry;
|
|
||||||
for (Iterator itr = paramTypes.entrySet().iterator();
|
|
||||||
itr.hasNext();) {
|
|
||||||
entry = (Map.Entry) itr.next();
|
|
||||||
if (!params.containsKey(entry.getKey()))
|
|
||||||
throw new UserException(_loc.get("unbound-param",
|
|
||||||
entry.getKey()));
|
|
||||||
if (((Class) entry.getValue()).isPrimitive()
|
|
||||||
&& params.get(entry.getKey()) == null)
|
|
||||||
throw new UserException(_loc.get("null-primitive-param",
|
|
||||||
entry.getKey()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check that there are no extra params
|
|
||||||
int typeCount = (paramTypes == null) ? 0 : paramTypes.size();
|
|
||||||
int paramCount = (params == null) ? 0 : params.size();
|
|
||||||
if (paramCount > typeCount)
|
|
||||||
throw new UserException(_loc.get("extra-params", new Object[]
|
|
||||||
{ new Integer(typeCount), new Integer(paramCount) }));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1708,7 +1613,7 @@ public class QueryImpl
|
|||||||
paramTypes.keySet()));
|
paramTypes.keySet()));
|
||||||
if (typeCount < params.length)
|
if (typeCount < params.length)
|
||||||
throw new UserException(_loc.get("extra-params", new Object[]
|
throw new UserException(_loc.get("extra-params", new Object[]
|
||||||
{ new Integer(typeCount), new Integer(params.length) }));
|
{ String.valueOf(typeCount), String.valueOf(params.length) }));
|
||||||
|
|
||||||
Iterator itr = paramTypes.entrySet().iterator();
|
Iterator itr = paramTypes.entrySet().iterator();
|
||||||
Map.Entry entry;
|
Map.Entry entry;
|
||||||
@ -1761,31 +1666,28 @@ public class QueryImpl
|
|||||||
implements StoreQuery.Executor {
|
implements StoreQuery.Executor {
|
||||||
|
|
||||||
private final StoreQuery.Executor[] _executors;
|
private final StoreQuery.Executor[] _executors;
|
||||||
private final QueryContext _ctx;
|
|
||||||
|
|
||||||
public MergedExecutor(StoreQuery.Executor[] executors,
|
public MergedExecutor(StoreQuery.Executor[] executors) {
|
||||||
QueryContext ctx) {
|
|
||||||
_executors = executors;
|
_executors = executors;
|
||||||
_ctx = ctx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
public ResultObjectProvider executeQuery(StoreQuery q,
|
||||||
Object[] params, boolean lrs, long startIdx, long endIdx) {
|
Object[] params, StoreQuery.Range range) {
|
||||||
if (_executors.length == 1)
|
if (_executors.length == 1)
|
||||||
return _executors[0].executeQuery(q, params, lrs, startIdx,
|
return _executors[0].executeQuery(q, params, range);
|
||||||
endIdx);
|
|
||||||
|
|
||||||
// use lrs settings if we couldn't take advantage of the start index
|
// use lrs settings if we couldn't take advantage of the start index
|
||||||
// so that hopefully the skip to the start will be efficient
|
// so that hopefully the skip to the start will be efficient
|
||||||
lrs = lrs || (startIdx > 0
|
StoreQuery.Range ropRange = new StoreQuery.Range(0, range.end);
|
||||||
&& _ctx.getFetchConfiguration().getFetchBatchSize() >= 0);
|
ropRange.lrs = range.lrs || (range.start > 0 && q.getContext().
|
||||||
|
getFetchConfiguration().getFetchBatchSize() >= 0);
|
||||||
|
|
||||||
// execute the query; we cannot use the lower bound of the result
|
// execute the query; we cannot use the lower bound of the result
|
||||||
// range, but we can take advantage of the upper bound
|
// range, but we can take advantage of the upper bound
|
||||||
ResultObjectProvider[] rops =
|
ResultObjectProvider[] rops =
|
||||||
new ResultObjectProvider[_executors.length];
|
new ResultObjectProvider[_executors.length];
|
||||||
for (int i = 0; i < _executors.length; i++)
|
for (int i = 0; i < _executors.length; i++)
|
||||||
rops[i] = _executors[i].executeQuery(q, params, lrs, 0, endIdx);
|
rops[i] = _executors[i].executeQuery(q, params, ropRange);
|
||||||
|
|
||||||
boolean[] asc = _executors[0].getAscending(q);
|
boolean[] asc = _executors[0].getAscending(q);
|
||||||
ResultObjectProvider rop;
|
ResultObjectProvider rop;
|
||||||
@ -1796,41 +1698,9 @@ public class QueryImpl
|
|||||||
_executors, q, params);
|
_executors, q, params);
|
||||||
|
|
||||||
// if there is a lower bound, wrap in range rop
|
// if there is a lower bound, wrap in range rop
|
||||||
if (startIdx != 0)
|
if (range.start != 0)
|
||||||
rop = new RangeResultObjectProvider(rop, startIdx, endIdx);
|
rop = new RangeResultObjectProvider(rop, range.start,
|
||||||
return rop;
|
range.end);
|
||||||
}
|
|
||||||
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q, Map params,
|
|
||||||
boolean lrs, long startIdx, long endIdx) {
|
|
||||||
if (_executors.length == 1)
|
|
||||||
return _executors[0].executeQuery(q, params, lrs, startIdx,
|
|
||||||
endIdx);
|
|
||||||
|
|
||||||
// use lrs settings if we couldn't take advantage of the start index
|
|
||||||
// so that hopefully the skip to the start will be efficient
|
|
||||||
lrs = lrs || (startIdx > 0
|
|
||||||
&& _ctx.getFetchConfiguration().getFetchBatchSize() >= 0);
|
|
||||||
|
|
||||||
// execute the query; we cannot use the lower bound of the result
|
|
||||||
// range, but we can take advantage of the upper bound
|
|
||||||
ResultObjectProvider[] rops =
|
|
||||||
new ResultObjectProvider[_executors.length];
|
|
||||||
for (int i = 0; i < _executors.length; i++)
|
|
||||||
rops[i] = _executors[i].executeQuery(q, params, lrs, 0, endIdx);
|
|
||||||
|
|
||||||
boolean[] asc = _executors[0].getAscending(q);
|
|
||||||
ResultObjectProvider rop;
|
|
||||||
if (asc.length == 0)
|
|
||||||
rop = new MergedResultObjectProvider(rops);
|
|
||||||
else
|
|
||||||
rop = new OrderingMergedResultObjectProvider(rops, asc,
|
|
||||||
_executors, q, _ctx.toParameterArray
|
|
||||||
(_executors[0].getParameterTypes(q), params));
|
|
||||||
|
|
||||||
// if there is a lower bound, wrap in range rop
|
|
||||||
if (startIdx != 0)
|
|
||||||
rop = new RangeResultObjectProvider(rop, startIdx, endIdx);
|
|
||||||
return rop;
|
return rop;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1841,13 +1711,6 @@ public class QueryImpl
|
|||||||
return Numbers.valueOf(num);
|
return Numbers.valueOf(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeDelete(StoreQuery q, Map params) {
|
|
||||||
long num = 0;
|
|
||||||
for (int i = 0; i < _executors.length; i++)
|
|
||||||
num += _executors[i].executeDelete(q, params).longValue();
|
|
||||||
return Numbers.valueOf(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Number executeUpdate(StoreQuery q, Object[] params) {
|
public Number executeUpdate(StoreQuery q, Object[] params) {
|
||||||
long num = 0;
|
long num = 0;
|
||||||
for (int i = 0; i < _executors.length; i++)
|
for (int i = 0; i < _executors.length; i++)
|
||||||
@ -1855,24 +1718,16 @@ public class QueryImpl
|
|||||||
return Numbers.valueOf(num);
|
return Numbers.valueOf(num);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Number executeUpdate(StoreQuery q, Map params) {
|
|
||||||
long num = 0;
|
|
||||||
for (int i = 0; i < _executors.length; i++)
|
|
||||||
num += _executors[i].executeUpdate(q, params).longValue();
|
|
||||||
return Numbers.valueOf(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
||||||
long startIdx, long endIdx) {
|
StoreQuery.Range range) {
|
||||||
if (_executors.length == 1)
|
if (_executors.length == 1)
|
||||||
return _executors[0].getDataStoreActions(q, params,
|
return _executors[0].getDataStoreActions(q, params, range);
|
||||||
startIdx, endIdx);
|
|
||||||
|
|
||||||
List results = new ArrayList(_executors.length);
|
List results = new ArrayList(_executors.length);
|
||||||
|
StoreQuery.Range ropRange = new StoreQuery.Range(0L, range.end);
|
||||||
String[] actions;
|
String[] actions;
|
||||||
for (int i = 0; i < _executors.length; i++) {
|
for (int i = 0; i < _executors.length; i++) {
|
||||||
actions = _executors[i].getDataStoreActions(q, params, 0,
|
actions = _executors[i].getDataStoreActions(q, params,ropRange);
|
||||||
endIdx);
|
|
||||||
if (actions != null && actions.length > 0)
|
if (actions != null && actions.length > 0)
|
||||||
results.addAll(Arrays.asList(actions));
|
results.addAll(Arrays.asList(actions));
|
||||||
}
|
}
|
||||||
@ -1883,6 +1738,11 @@ public class QueryImpl
|
|||||||
_executors[0].validate(q);
|
_executors[0].validate(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void getRange(StoreQuery q, Object[] params,
|
||||||
|
StoreQuery.Range range) {
|
||||||
|
_executors[0].getRange(q, params, range);
|
||||||
|
}
|
||||||
|
|
||||||
public Object getOrderingValue(StoreQuery q, Object[] params,
|
public Object getOrderingValue(StoreQuery q, Object[] params,
|
||||||
Object resultObject, int idx) {
|
Object resultObject, int idx) {
|
||||||
// unfortunately, at this point (must be a merged rop containing
|
// unfortunately, at this point (must be a merged rop containing
|
||||||
|
@ -89,9 +89,12 @@ class SingleFieldManager
|
|||||||
proxy = checkProxy();
|
proxy = checkProxy();
|
||||||
if (proxy == null) {
|
if (proxy == null) {
|
||||||
proxy = (Proxy) _sm.newFieldProxy(field);
|
proxy = (Proxy) _sm.newFieldProxy(field);
|
||||||
if (objval != null)
|
if (objval != null) {
|
||||||
((Calendar) proxy).setTime(((Calendar) objval).
|
Calendar pcal = (Calendar) proxy;
|
||||||
getTime());
|
Calendar ocal = (Calendar) objval;
|
||||||
|
pcal.setTime(ocal.getTime());
|
||||||
|
pcal.setTimeZone(ocal.getTimeZone());
|
||||||
|
}
|
||||||
ret = true;
|
ret = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -158,6 +158,23 @@ public interface StoreQuery
|
|||||||
*/
|
*/
|
||||||
public boolean supportsParameterDeclarations();
|
public boolean supportsParameterDeclarations();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A query result range.
|
||||||
|
*/
|
||||||
|
public static class Range {
|
||||||
|
public long start = 0L;
|
||||||
|
public long end = Long.MAX_VALUE;
|
||||||
|
public boolean lrs = false;
|
||||||
|
|
||||||
|
public Range() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Range(long start, long end) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An executor provides a uniform interface to the mechanism for executing
|
* An executor provides a uniform interface to the mechanism for executing
|
||||||
* either an in-memory or datastore query. In the common case, the
|
* either an in-memory or datastore query. In the common case, the
|
||||||
@ -179,17 +196,8 @@ public interface StoreQuery
|
|||||||
* aggregate and does not have grouping
|
* aggregate and does not have grouping
|
||||||
* @see #isPacking
|
* @see #isPacking
|
||||||
*/
|
*/
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q,
|
public ResultObjectProvider executeQuery(StoreQuery q, Object[] params,
|
||||||
Object[] params, boolean lrs, long startIdx, long endIdx);
|
Range range);
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the result of executing this query with the given parameter
|
|
||||||
* values. Most implementation will use
|
|
||||||
* {@link QueryContext#toParameterArray} to transform the parameters
|
|
||||||
* into an array and invoke the array version of this method.
|
|
||||||
*/
|
|
||||||
public ResultObjectProvider executeQuery(StoreQuery q, Map params,
|
|
||||||
boolean lrs, long startIdx, long endIdx);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Deleted the objects that result from the execution of the
|
* Deleted the objects that result from the execution of the
|
||||||
@ -197,36 +205,30 @@ public interface StoreQuery
|
|||||||
*/
|
*/
|
||||||
public Number executeDelete(StoreQuery q, Object[] params);
|
public Number executeDelete(StoreQuery q, Object[] params);
|
||||||
|
|
||||||
/**
|
|
||||||
* Deleted the objects that result from the execution of the
|
|
||||||
* query, retuning the number of objects that were deleted.
|
|
||||||
*/
|
|
||||||
public Number executeDelete(StoreQuery q, Map params);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the objects that result from the execution of the
|
* Updates the objects that result from the execution of the
|
||||||
* query, retuning the number of objects that were updated.
|
* query, retuning the number of objects that were updated.
|
||||||
*/
|
*/
|
||||||
public Number executeUpdate(StoreQuery q, Object[] params);
|
public Number executeUpdate(StoreQuery q, Object[] params);
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the objects that result from the execution of the
|
|
||||||
* query, retuning the number of objects that were updated.
|
|
||||||
*/
|
|
||||||
public Number executeUpdate(StoreQuery q, Map params);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a description of the commands that will be sent to
|
* Return a description of the commands that will be sent to
|
||||||
* the datastore in order to execute the query.
|
* the datastore in order to execute the query.
|
||||||
*/
|
*/
|
||||||
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
public String[] getDataStoreActions(StoreQuery q, Object[] params,
|
||||||
long startIdx, long endIdx);
|
Range range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate components of query.
|
* Validate components of query.
|
||||||
*/
|
*/
|
||||||
public void validate(StoreQuery q);
|
public void validate(StoreQuery q);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mutate the given range to set any range information stored in
|
||||||
|
* the query string and/or parameters.
|
||||||
|
*/
|
||||||
|
public void getRange(StoreQuery q, Object[] params, Range range);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the value of the <code>orderIndex</code>th ordering
|
* Extract the value of the <code>orderIndex</code>th ordering
|
||||||
* expression in {@link Query#getOrderingClauses} from the
|
* expression in {@link Query#getOrderingClauses} from the
|
||||||
|
@ -16,12 +16,11 @@
|
|||||||
package org.apache.openjpa.kernel.exps;
|
package org.apache.openjpa.kernel.exps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for any constant value.
|
* Interface for any query constant value.
|
||||||
*
|
*
|
||||||
* @author Marc Prud'hommeaux
|
* @author Marc Prud'hommeaux
|
||||||
*/
|
*/
|
||||||
public interface Constant
|
public interface Constant {
|
||||||
extends Value {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value for this constant given the specified parameters.
|
* Return the value for this constant given the specified parameters.
|
||||||
|
@ -22,7 +22,7 @@ package org.apache.openjpa.kernel.exps;
|
|||||||
* @nojavadoc
|
* @nojavadoc
|
||||||
*/
|
*/
|
||||||
public interface Literal
|
public interface Literal
|
||||||
extends Constant {
|
extends Value, Constant {
|
||||||
|
|
||||||
public static final int TYPE_UNKNOWN = 0;
|
public static final int TYPE_UNKNOWN = 0;
|
||||||
public static final int TYPE_NUMBER = 1;
|
public static final int TYPE_NUMBER = 1;
|
||||||
|
@ -22,7 +22,7 @@ package org.apache.openjpa.kernel.exps;
|
|||||||
* @nojavadoc
|
* @nojavadoc
|
||||||
*/
|
*/
|
||||||
public interface Parameter
|
public interface Parameter
|
||||||
extends Constant {
|
extends Value, Constant {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the index of this parameter.
|
* Set the index of this parameter.
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.openjpa.kernel.exps;
|
package org.apache.openjpa.kernel.exps;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.commons.collections.map.LinkedMap;
|
import org.apache.commons.collections.map.LinkedMap;
|
||||||
@ -40,8 +42,7 @@ public class QueryExpressions {
|
|||||||
/**
|
/**
|
||||||
* Map of {@link FieldMetaData},{@link Value} for update statements.
|
* Map of {@link FieldMetaData},{@link Value} for update statements.
|
||||||
*/
|
*/
|
||||||
public Map updates = null;
|
public Map updates = Collections.EMPTY_MAP;
|
||||||
|
|
||||||
public int distinct = DISTINCT_AUTO;
|
public int distinct = DISTINCT_AUTO;
|
||||||
public String alias = null;
|
public String alias = null;
|
||||||
public Value[] projections = EMPTY_VALUES;
|
public Value[] projections = EMPTY_VALUES;
|
||||||
@ -59,8 +60,12 @@ public class QueryExpressions {
|
|||||||
public int operation = QueryOperations.OP_SELECT;
|
public int operation = QueryOperations.OP_SELECT;
|
||||||
public ClassMetaData[] accessPath = StoreQuery.EMPTY_METAS;
|
public ClassMetaData[] accessPath = StoreQuery.EMPTY_METAS;
|
||||||
public String[] fetchPaths = StoreQuery.EMPTY_STRINGS;
|
public String[] fetchPaths = StoreQuery.EMPTY_STRINGS;
|
||||||
|
public Value[] range = EMPTY_VALUES;
|
||||||
private Boolean _aggregate = null;
|
private Boolean _aggregate = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this is an aggregate results.
|
||||||
|
*/
|
||||||
public boolean isAggregate() {
|
public boolean isAggregate() {
|
||||||
if (projections.length == 0)
|
if (projections.length == 0)
|
||||||
return false;
|
return false;
|
||||||
@ -70,6 +75,15 @@ public class QueryExpressions {
|
|||||||
return _aggregate.booleanValue();
|
return _aggregate.booleanValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an update.
|
||||||
|
*/
|
||||||
|
public void putUpdate(FieldMetaData fmd, Value val) {
|
||||||
|
if (updates == Collections.EMPTY_MAP)
|
||||||
|
updates = new HashMap();
|
||||||
|
updates.put(fmd, val);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visitor to determine whether our projections are aggregates.
|
* Visitor to determine whether our projections are aggregates.
|
||||||
*/
|
*/
|
||||||
|
@ -42,8 +42,7 @@ class SubQ
|
|||||||
return _alias;
|
return _alias;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setQueryExpressions(QueryExpressions q, long startIdx,
|
public void setQueryExpressions(QueryExpressions q) {
|
||||||
long endIdx) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Class getType() {
|
public Class getType() {
|
||||||
|
@ -32,6 +32,5 @@ public interface Subquery
|
|||||||
/**
|
/**
|
||||||
* Set the parsed subquery.
|
* Set the parsed subquery.
|
||||||
*/
|
*/
|
||||||
public void setQueryExpressions(QueryExpressions query, long startIdx,
|
public void setQueryExpressions(QueryExpressions query);
|
||||||
long endIdx);
|
|
||||||
}
|
}
|
||||||
|
@ -444,30 +444,18 @@ class JPQLExpressionBuilder
|
|||||||
protected void evalSetClause(QueryExpressions exps) {
|
protected void evalSetClause(QueryExpressions exps) {
|
||||||
// handle SET field = value
|
// handle SET field = value
|
||||||
JPQLNode[] nodes = root().findChildrenByID(JJTUPDATEITEM);
|
JPQLNode[] nodes = root().findChildrenByID(JJTUPDATEITEM);
|
||||||
|
|
||||||
Map updates = null;
|
|
||||||
|
|
||||||
for (int i = 0; nodes != null && i < nodes.length; i++) {
|
for (int i = 0; nodes != null && i < nodes.length; i++) {
|
||||||
if (updates == null)
|
|
||||||
updates = new HashMap();
|
|
||||||
|
|
||||||
FieldMetaData field = getPath(firstChild(nodes[i])).last();
|
FieldMetaData field = getPath(firstChild(nodes[i])).last();
|
||||||
Value val = getValue(onlyChild(lastChild(nodes[i])));
|
Value val = getValue(onlyChild(lastChild(nodes[i])));
|
||||||
|
exps.putUpdate(field, val);
|
||||||
updates.put(field, val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (updates != null)
|
|
||||||
exps.updates = updates;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Expression evalWhereClause(QueryExpressions exps) {
|
private Expression evalWhereClause(QueryExpressions exps) {
|
||||||
// evaluate the WHERE clause
|
// evaluate the WHERE clause
|
||||||
JPQLNode whereNode = root().findChildByID(JJTWHERE, false);
|
JPQLNode whereNode = root().findChildByID(JJTWHERE, false);
|
||||||
|
|
||||||
if (whereNode == null)
|
if (whereNode == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return (Expression) eval(whereNode);
|
return (Expression) eval(whereNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1110,7 +1098,7 @@ class JPQLExpressionBuilder
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
QueryExpressions subexp = getQueryExpressions();
|
QueryExpressions subexp = getQueryExpressions();
|
||||||
subq.setQueryExpressions(subexp, 0, Long.MAX_VALUE);
|
subq.setQueryExpressions(subexp);
|
||||||
return subq;
|
return subq;
|
||||||
} finally {
|
} finally {
|
||||||
// remove the subquery parse context
|
// remove the subquery parse context
|
||||||
|
28
openjpa-kernel/src/main/java/sun/misc/Perf.java
Normal file
28
openjpa-kernel/src/main/java/sun/misc/Perf.java
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package sun.misc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compilation stub for pre-1.4.2 JREs. Thanks to it, the whole backport
|
||||||
|
* concurrency package compiles and works with 1.4.2 as well as wih earlier
|
||||||
|
* JREs, and takes advantage of native Perf class when running on 1.4.2 while
|
||||||
|
* seamlessly falling back to System.currentTimeMillis() on previous JREs. This
|
||||||
|
* class should NOT be included in the binary distribution of backport.
|
||||||
|
*
|
||||||
|
* @author Dawid Kurzyniec
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public final class Perf {
|
||||||
|
|
||||||
|
private static final Perf perf = new Perf();
|
||||||
|
|
||||||
|
public static Perf getPerf() { return perf; }
|
||||||
|
|
||||||
|
private Perf() {}
|
||||||
|
|
||||||
|
public long highResCounter() {
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long highResFrequency() {
|
||||||
|
return 1000L;
|
||||||
|
}
|
||||||
|
}
|
@ -4,8 +4,6 @@ in-mem-subquery: Subqueries are not supported for queries that execute \
|
|||||||
not-comp: The evaluation of the ordering expression of this query produced \
|
not-comp: The evaluation of the ordering expression of this query produced \
|
||||||
non-comparable values "{0}" and "{1}". Please check that the ordering \
|
non-comparable values "{0}" and "{1}". Please check that the ordering \
|
||||||
clause is valid.
|
clause is valid.
|
||||||
bad-wild: The wildcard string "{0}" is invalid.
|
|
||||||
bad-regexp: The regular expression string "{0}" is invalid.
|
|
||||||
agg-in-filter: If you use an aggregate function in a query filter, you must \
|
agg-in-filter: If you use an aggregate function in a query filter, you must \
|
||||||
make sure to only invoke the aggregate on collections.
|
make sure to only invoke the aggregate on collections.
|
||||||
parse-error: An error occurred while parsing the query filter "{1}". \
|
parse-error: An error occurred while parsing the query filter "{1}". \
|
||||||
|
@ -166,7 +166,9 @@ inverse-consistency: An inverse inconsistency in the object model was \
|
|||||||
detected while flushing the field "{0}" of the instance with id "{1}" \
|
detected while flushing the field "{0}" of the instance with id "{1}" \
|
||||||
in context "{2}".
|
in context "{2}".
|
||||||
no-brokerfactory: You did not name the factory class with the required \
|
no-brokerfactory: You did not name the factory class with the required \
|
||||||
property org.apache.openjpa.BrokerFactory.
|
property openjpa.BrokerFactory. Normally this property defaults \
|
||||||
|
appropriately; have you forgotten to include all the OpenJPA jars in your \
|
||||||
|
classpath?
|
||||||
brokerfactory-excep: There was an error when invoking the static \
|
brokerfactory-excep: There was an error when invoking the static \
|
||||||
getInstance method on the named factory class "{0}". See the \
|
getInstance method on the named factory class "{0}". See the \
|
||||||
nested exception for details.
|
nested exception for details.
|
||||||
@ -226,7 +228,7 @@ force-in-mem: This query on type "{0}" must load the entire candidate class \
|
|||||||
there are dirty instances that may affect the query''s outcome in the \
|
there are dirty instances that may affect the query''s outcome in the \
|
||||||
cache.
|
cache.
|
||||||
cant-exec-inmem: Queries of this type ("{0}") cannot be executed in-memory. \
|
cant-exec-inmem: Queries of this type ("{0}") cannot be executed in-memory. \
|
||||||
Either set IgnoreCache to true, set the org.apache.openjpa.FlushBeforeQueries \
|
Either set IgnoreCache to true, set the openjpa.FlushBeforeQueries \
|
||||||
property to true, or execute the query before changing any instances in \
|
property to true, or execute the query before changing any instances in \
|
||||||
the transaction.
|
the transaction.
|
||||||
executing-query: Executing query: {0}
|
executing-query: Executing query: {0}
|
||||||
@ -269,9 +271,9 @@ bad-method-class: You set the method name of this openjpa.MethodQL query to \
|
|||||||
"{1}", but class "{0}" is not a valid class name. Make sure to fully \
|
"{1}", but class "{0}" is not a valid class name. Make sure to fully \
|
||||||
qualify the class name or to import its package into this query if the \
|
qualify the class name or to import its package into this query if the \
|
||||||
class is not in the query candidate class'' package.
|
class is not in the query candidate class'' package.
|
||||||
method-not-static: Method "{0}" named in the org.apache.openjpa.MethodQL query must be static.
|
method-not-static: Method "{0}" named in the MethodQL query must be static.
|
||||||
no-method: You must set the query filter to the name of the method to execute \
|
no-method: You must set the query filter to the name of the method to execute \
|
||||||
for this org.apache.openjpa.MethodQL query instance.
|
for this MethodQL query instance.
|
||||||
method-error: There was an error invoking method "{0}" with arguments "{1}".
|
method-error: There was an error invoking method "{0}" with arguments "{1}".
|
||||||
bad-param-type: The type "{0}" as used in the parameter declarations \
|
bad-param-type: The type "{0}" as used in the parameter declarations \
|
||||||
could not be found in the imports.
|
could not be found in the imports.
|
||||||
@ -295,13 +297,15 @@ bad-inmem-method: Method "{0}(StoreContext, ClassMetaData, boolean, Object, \
|
|||||||
true.
|
true.
|
||||||
bad-datastore-method: Method "{0}(StoreContext, ClassMetaData, boolean, Map, \
|
bad-datastore-method: Method "{0}(StoreContext, ClassMetaData, boolean, Map, \
|
||||||
FetchConfiguration)" is not declared in type "{1}". Check \
|
FetchConfiguration)" is not declared in type "{1}". Check \
|
||||||
the method name supplied in your org.apache.openjpa.MethodQL query filter. OpenJPA is \
|
the method name supplied in your MethodQL query filter. OpenJPA is \
|
||||||
attempting to execute this query against the datastore; if you implemented \
|
attempting to execute this query against the datastore; if you implemented \
|
||||||
the in-memory method instead (a method with the same signature but with an \
|
the in-memory method instead (a method with the same signature but with an \
|
||||||
Object argument) and want this query to execute in-memory, supplly a \
|
Object argument) and want this query to execute in-memory, supplly a \
|
||||||
Collection of candidates to filter.
|
Collection of candidates to filter.
|
||||||
only-update-primitives: Bulk update queries when executed in memory \
|
only-update-constants: Bulk update queries when executed in memory \
|
||||||
may only change the value of primitives and simple Object fields.
|
may only update to constant values.
|
||||||
|
only-range-constants: Range values must be numeric constants. Illegal query: \
|
||||||
|
{0}
|
||||||
no-savepoint-copy: Unable to copy field "{0}" for savepoint.
|
no-savepoint-copy: Unable to copy field "{0}" for savepoint.
|
||||||
savepoint-exists: A savepoint with the name "{0}" already exists. \
|
savepoint-exists: A savepoint with the name "{0}" already exists. \
|
||||||
Each savepoint name must be unique.
|
Each savepoint name must be unique.
|
||||||
|
@ -16,8 +16,8 @@ bad-second: "{0}" declares a secondary table on columns that do not support \
|
|||||||
unique-constraints: Detected declared unique constraints on "{0}". OpenJPA \
|
unique-constraints: Detected declared unique constraints on "{0}". OpenJPA \
|
||||||
does not yet support the @UniqueConstraint annotation.
|
does not yet support the @UniqueConstraint annotation.
|
||||||
inconsist-col-attrs: Detected inconsistent values of "unique" on different \
|
inconsist-col-attrs: Detected inconsistent values of "unique" on different \
|
||||||
columns of "{0}". OpenJPA does not yet support different per-column unique \
|
columns of "{0}". OpenJPA does not yet support different per-column \
|
||||||
values. All columns for this mapping must use the same values.
|
unique values. All columns for this mapping must use the same values.
|
||||||
pk-as-fk: The "usePKasFK" attribute is not yet supported. Mapping your \
|
pk-as-fk: The "usePKasFK" attribute is not yet supported. Mapping your \
|
||||||
OneToOne using JoinColumns that match your id property columns will work.
|
OneToOne using JoinColumns that match your id property columns will work.
|
||||||
no-override-name: Missing "name" property on mapping override for "{0}".
|
no-override-name: Missing "name" property on mapping override for "{0}".
|
||||||
|
Loading…
x
Reference in New Issue
Block a user