Modified: openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java?rev=687120&r1=687119&r2=687120&view=diff ============================================================================== --- openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java (original) +++ openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java Tue Aug 19 11:40:34 2008 @@ -20,10 +20,7 @@ import java.io.Serializable; import java.lang.reflect.Method; -import java.sql.Time; -import java.sql.Timestamp; import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; @@ -33,8 +30,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.TreeMap; - import javax.persistence.FlushModeType; import javax.persistence.Query; import javax.persistence.TemporalType; @@ -72,17 +67,18 @@ private transient EntityManagerImpl _em; private transient FetchPlan _fetch; - private Map<String, Object> _named; - private Map<Integer, Object> _positional; - - private static Object GAP_FILLER = new Object(); + private Map _named; + private List _positional; /** * Constructor; supply factory exception translator and delegate. * - * @param em The EntityManager which created this query - * @param ret Exception translater for this query - * @param query The underlying "kernel" query. + * @param em + * The EntityManager which created this query + * @param ret + * Exception translater for this query + * @param query + * The underlying "kernel" query. */ public QueryImpl(EntityManagerImpl em, RuntimeExceptionTranslator ret, org.apache.openjpa.kernel.Query query) { @@ -250,179 +246,47 @@ validateParameters(); - // handle which types of parameters we are using, if any - if (_positional != null) - return _query.execute(_positional); - if (_named != null) - return _query.execute(_named); - return _query.execute(); - } - - /** - * Validate that the types of the parameters are correct. - * The idea is to catch as many validation error as possible at the facade - * layer itself. - * For native SQL queries, however, parameter validation is bypassed as - * we do not parse SQL. - * - * The expected parameters are parsed from the query and in a LinkedMap - * key : name of the parameter as declared in query - * value : expected Class of allowed value - * - * The bound parameters depends on positional or named parameter style - * - * TreeMap<Integer, Object> for positional parameters: - * key : 1-based Integer index - * value : bound value. GAP_FILLER if the position is not set. This - * simplifies validation at the kernel layer - * - * Map<String, Object> for named parameters: - * key : parameter name - * value : the bound value - * - * Validation accounts for - * a) gaps in positional parameters - * SELECT p FROM PObject p WHERE p.a1=?1 AND p.a3=?3 - * - * b) repeated parameters - * SELECT p FROM PObject p WHERE p.a1=?1 AND p.a2=?1 AND p.a3=?2 - * - * c) parameter is bound but not declared - * - * d) parameter is declared but not bound - * - * e) parameter does not match the value type - * - * f) parameter is primitive type but bound to null value - */ - private void validateParameters() { - if (isNative()) { - removeGaps(_positional); - return; - } - String query = getQueryString(); - if (_positional != null) { - LinkedMap expected = _query.getParameterTypes(); - Map<Integer, Object> actual = _positional; - for (Object o : expected.keySet()) { - String position = (String) o; - Class expectedParamType = (Class) expected.get(position); - try { - Integer.parseInt(position); - } catch (NumberFormatException ex) { - newValidationException("param-style-mismatch", query, - expected.asList(), - Arrays.toString(actual.keySet().toArray())); - } - Object actualValue = actual.get(Integer.parseInt(position)); - boolean valueUnspecified = (actualValue == GAP_FILLER) - || (actualValue == null && (actual.size() < expected - .size())); - if (valueUnspecified) - newValidationException("param-missing", position, query, - Arrays.toString(actual.keySet().toArray())); - - if (expectedParamType.isPrimitive() && actualValue == null) - newValidationException("param-type-null", - position, query, expectedParamType.getName()); - if (actualValue != null && - !Filters.wrap(expectedParamType).isInstance(actualValue)) - newValidationException("param-type-mismatch", - position, query, actualValue, - actualValue.getClass().getName(), - expectedParamType.getName()); - - } - for (Integer position : actual.keySet()) { - Object actualValue = actual.get(position); - Class expectedParamType = (Class) expected.get("" + position); - boolean paramExpected = expected.containsKey("" + position); - if (actualValue == GAP_FILLER) { - if (paramExpected) { - newValidationException("param-missing", position, query, - Arrays.toString(actual.keySet().toArray())); - } - } else { - if (!paramExpected) - newValidationException("param-extra", position, query, - expected.asList()); - if (expectedParamType.isPrimitive() && actualValue == null) - newValidationException("param-type-null", - position, query, expectedParamType.getName()); - if (actualValue != null - && !Filters.wrap(expectedParamType).isInstance(actualValue)) - newValidationException("param-type-mismatch", - position, query, actualValue, - actualValue.getClass().getName(), - expectedParamType.getName()); - - } - } - - } else if (_named != null) { - LinkedMap expected = _query.getParameterTypes(); - // key : name of the parameter used while binding - // value : user supplied parameter value. null may mean either - // user has supplied a value or not specified at all - Map<String, Object> actual = _named; - for (Object o : expected.keySet()) { - String expectedName = (String) o; - Class expectedParamType = (Class) expected.get(expectedName); - Object actualValue = actual.get(expectedName); - boolean valueUnspecified = !actual.containsKey(expectedName); - if (valueUnspecified) { - newValidationException("param-missing", expectedName, query, - Arrays.toString(actual.keySet().toArray())); - } - if (expectedParamType.isPrimitive() && actualValue == null) - newValidationException("param-type-null", - expectedName, query, expectedParamType.getName()); - if (actualValue != null - && !Filters.wrap(expectedParamType).isInstance(actualValue)) { - newValidationException("param-type-mismatch", - expectedName, query, actualValue, - actualValue.getClass().getName(), - expectedParamType.getName()); - } - } - for (String actualName : actual.keySet()) { - Object actualValue = actual.get(actualName); - Class expectedParamType = (Class) expected.get(actualName); - boolean paramExpected = expected.containsKey(actualName); - if (!paramExpected) { - newValidationException("param-extra", actualName, query, - expected.asList()); - } - if (expectedParamType.isPrimitive() && actualValue == null) - newValidationException("param-type-null", - actualName, query, expectedParamType.getName()); - if (actualValue != null - && !Filters.wrap(expectedParamType).isInstance(actualValue)) { - newValidationException("param-type-mismatch", - actualName, query, actualValue, - actualValue.getClass().getName(), - expectedParamType.getName()); - } - } - } - } - - Map<Integer, Object> removeGaps(Map<Integer, Object> map) { - if (map == null || !map.containsValue(GAP_FILLER)) - return map; - List<Integer> gaps = new ArrayList<Integer>(); - for (Integer key : map.keySet()) - if (map.get(key) == GAP_FILLER) - gaps.add(key); - for (Integer gap : gaps) { - map.remove(gap); - } - return map; - } + // handle which types of parameters we are using, if any + if (_positional != null) + return _query.execute(_positional.toArray()); + if (_named != null) + return _query.execute(_named); + return _query.execute(); + } - void newValidationException(String msgKey, Object...args) { - throw new ArgumentException(_loc.get(msgKey, args), null, null, false); - } + /** + * Validate that the types of the parameters are correct. + */ + private void validateParameters() { + if (_positional != null) { + LinkedMap types = _query.getParameterTypes(); + for (int i = 0, + size = Math.min(_positional.size(), types.size()); + i < size; i++) + validateParameter(String.valueOf(i), + (Class) types.getValue(i), _positional.get(i)); + } else if (_named != null) { + Map types = _query.getParameterTypes(); + for (Iterator i = _named.entrySet().iterator(); i.hasNext();) { + Map.Entry entry = (Map.Entry) i.next(); + String name = (String) entry.getKey(); + validateParameter(name, (Class) types.get(name), + entry.getValue()); + } + } + } + + private void validateParameter(String paramDesc, Class type, Object param) { + // null parameters are allowed, so are not validated + if (param == null || type == null) + return; + + // check the parameter against the wrapped type + if (!Filters.wrap(type).isInstance(param)) + throw new ArgumentException(_loc.get("bad-param-type", + paramDesc, param.getClass().getName(), type.getName()), + null, null, false); + } public List getResultList() { _em.assertNotCloseInvoked(); @@ -460,7 +324,7 @@ if (_query.getOperation() == QueryOperations.OP_DELETE) { // handle which types of parameters we are using, if any if (_positional != null) - return asInt(_query.deleteAll(_positional)); + return asInt(_query.deleteAll(_positional.toArray())); if (_named != null) return asInt(_query.deleteAll(_named)); return asInt(_query.deleteAll()); @@ -468,7 +332,7 @@ if (_query.getOperation() == QueryOperations.OP_UPDATE) { // handle which types of parameters we are using, if any if (_positional != null) - return asInt(_query.updateAll(_positional)); + return asInt(_query.updateAll(_positional.toArray())); if (_named != null) return asInt(_query.updateAll(_named)); return asInt(_query.updateAll()); @@ -569,76 +433,57 @@ public OpenJPAQuery setParameter(int position, Calendar value, TemporalType t) { - return setParameter(position, convertTemporalType(value, t)); + return setParameter(position, value); } public OpenJPAQuery setParameter(int position, Date value, TemporalType type) { - return setParameter(position, convertTemporalType(value, type)); + return setParameter(position, value); } - /** - * Converts the given Date to a value corresponding to given temporal type. - */ - Object convertTemporalType(Date value, TemporalType type) { - switch (type) { - case DATE: - return value; - case TIME: - return new Time(value.getTime()); - case TIMESTAMP: - return new Timestamp(value.getTime()); - default: - return null; - } - } - - Object convertTemporalType(Calendar value, TemporalType type) { - return convertTemporalType(value.getTime(), type); - } - public OpenJPAQuery setParameter(int position, Object value) { - _query.assertOpen(); - _em.assertNotCloseInvoked(); - _query.lock(); - try { - if (isNative() && position < 1) { - throw new IllegalArgumentException(_loc.get("bad-pos-params", - position, _query.getQueryString()).toString()); - } - // not allowed to mix positional and named parameters (EDR2 3.6.4) - if (_named != null) - throw new InvalidStateException(_loc.get( - "no-pos-named-params-mix", _query.getQueryString()), - null, null, false); - - if (position < 1) - throw new InvalidStateException(_loc.get("illegal-index", - position), null, null, false); - - if (_positional == null) - _positional = new TreeMap<Integer, Object>(); - - _positional.put(position, value); - for (int i = 1; i < position; i++) - if (!_positional.containsKey(i)) - _positional.put(i, GAP_FILLER); - - return this; - } finally { - _query.unlock(); - } - } + _query.assertOpen(); + _em.assertNotCloseInvoked(); + _query.lock(); + try { + if (isNative() && position < 1) { + throw new IllegalArgumentException(_loc.get("bad-pos-params", + position, _query.getQueryString()).toString()); + } + // not allowed to mix positional and named parameters (EDR2 3.6.4) + if (_named != null) + throw new InvalidStateException(_loc.get + ("no-pos-named-params-mix", _query.getQueryString()), + null, null, false); + + if (position < 1) + throw new InvalidStateException(_loc.get + ("illegal-index", position), null, null, false); + if (_positional == null) + _positional = new ArrayList(); + + // make sure it is at least the requested size + while (_positional.size() < position) + _positional.add(null); + + // note that we add it to position - 1, since setPosition + // starts at 1, while List starts at 0 + _positional.set(position - 1, value); + return this; + } finally { + _query.unlock(); + } + } public OpenJPAQuery setParameter(String name, Calendar value, TemporalType t) { - return setParameter(name, convertTemporalType(value, t)); + return setParameter(name, value); } public OpenJPAQuery setParameter(String name, Date value, TemporalType type) { - return setParameter(name, convertTemporalType(value, type)); + return setParameter(name, value); } public OpenJPAQuery setParameter(String name, Object value) { @@ -673,21 +518,14 @@ return _positional != null; } - /** - * Gets the array of positional parameter values. A value of - * <code>GAP_FILLER</code> indicates that user has not set the - * corresponding positional parameter. A value of null implies that user has - * set the value as null. - */ - public Object[] getPositionalParameters() { - _query.lock(); - try { - return (_positional == null) ? EMPTY_ARRAY : _positional.values() - .toArray(); - } finally { - _query.unlock(); - } - } + public Object[] getPositionalParameters() { + _query.lock(); + try { + return (_positional == null) ? EMPTY_ARRAY : _positional.toArray(); + } finally { + _query.unlock(); + } + } public OpenJPAQuery setParameters(Object... params) { _query.assertOpen();
Modified: openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java?rev=687120&r1=687119&r2=687120&view=diff ============================================================================== --- openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java (original) +++ openjpa/branches/1.2.x/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/XMLPersistenceMetaDataParser.java Tue Aug 19 11:40:34 2008 @@ -1391,15 +1391,9 @@ if (log.isTraceEnabled()) log.trace(_loc.get("parse-query", name)); - QueryMetaData meta = getRepository().searchQueryMetaDataByName(name); - if (meta != null) { - Class defType = meta.getDefiningType(); - if ((defType != _cls) && log.isWarnEnabled()) { - log.warn(_loc.get("dup-query", name, currentLocation(), defType)); - } - pushElement(meta); - return true; - } + QueryMetaData meta = getRepository().getCachedQueryMetaData(null, name); + if (meta != null && log.isWarnEnabled()) + log.warn(_loc.get("override-query", name, currentLocation())); meta = getRepository().addQueryMetaData(null, name); meta.setDefiningType(_cls); Modified: openjpa/branches/1.2.x/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties?rev=687120&r1=687119&r2=687120&view=diff ============================================================================== --- openjpa/branches/1.2.x/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties (original) +++ openjpa/branches/1.2.x/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties Tue Aug 19 11:40:34 2008 @@ -34,8 +34,7 @@ dup-sequence: Found duplicate generator "{0}" in "{1}". Ignoring. override-sequence: Found duplicate generator "{0}" in "{1}". Overriding \ previous definition. -dup-query: Ignoring duplicate query "{0}" in "{1}". A query with the same name \ - been already declared in "{2}". +dup-query: Found duplicate query "{0}" in "{1}". Ignoring. override-query: Found duplicate query "{0}" in "{1}". Overriding previous \ definition. no-seq-name: The sequence generator in "{0}" must declare a name. @@ -149,13 +148,4 @@ EntityManagerFactory-displayorder: 50 EntityManagerFactory-expert: true EntityManagerFactory-interface: org.apache.openjpa.persistence.EntityManagerFactoryImpl -param-style-mismatch: Query "{0}" is declared with named parameters "{1}" but \ - actual parameters "{2}" are bound by position. -param-missing: Parameter "{0}" declared in "{1}" but is missing from the bound \ - parameters "{2}". -param-extra: Parameter "{0}" is bound to "{1}" but is missing from the \ - declared parameters "{2}". -param-type-mismatch: Parameter "{0}" declared in "{1}" is set to value of \ - "{2}" of type "{3}", but this parameter is bound to a field of type "{4}". -param-type-null: Parameter "{0}" declared in "{1}" is set to null, \ - but this parameter is bound to a field of primitive type "{2}". + Modified: openjpa/branches/1.2.x/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java?rev=687120&r1=687119&r2=687120&view=diff ============================================================================== --- openjpa/branches/1.2.x/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java (original) +++ openjpa/branches/1.2.x/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreManager.java Tue Aug 19 11:40:34 2008 @@ -102,10 +102,6 @@ public DistributedJDBCConfiguration getConfiguration() { return _conf; } - - public SliceStoreManager getSlice(int i) { - return _slices.get(i); - } /** * Decides the index of the StoreManager by first looking at the Modified: openjpa/branches/1.2.x/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java URL: http://svn.apache.org/viewvc/openjpa/branches/1.2.x/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java?rev=687120&r1=687119&r2=687120&view=diff ============================================================================== --- openjpa/branches/1.2.x/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java (original) +++ openjpa/branches/1.2.x/openjpa-slice/src/main/java/org/apache/openjpa/slice/jdbc/DistributedStoreQuery.java Tue Aug 19 11:40:34 2008 @@ -32,7 +32,6 @@ import org.apache.openjpa.kernel.FetchConfiguration; import org.apache.openjpa.kernel.OrderingMergedResultObjectProvider; import org.apache.openjpa.kernel.QueryContext; -import org.apache.openjpa.kernel.StoreManager; import org.apache.openjpa.kernel.StoreQuery; import org.apache.openjpa.kernel.exps.ExpressionParser; import org.apache.openjpa.lib.rop.MergedResultObjectProvider; @@ -62,15 +61,17 @@ _queries.add(q); } - public DistributedStoreManager getDistributedStore() { - return (DistributedStoreManager)getStore(); - } - public Executor newDataStoreExecutor(ClassMetaData meta, boolean subs) { ParallelExecutor ex = new ParallelExecutor(this, meta, subs, _parser, ctx.getCompilation()); - for (StoreQuery q : _queries) { - ex.addExecutor(q.newDataStoreExecutor(meta, subs)); + + FetchConfiguration fetch = getContext().getFetchConfiguration(); + DistributedStoreManager store = (DistributedStoreManager)getContext() + .getStoreContext().getStoreManager().getInnermostDelegate(); + List<SliceStoreManager> targets = store.getTargets(fetch); + for (StoreQuery q:_queries) { + if (targets.contains(((JDBCStoreQuery)q).getStore())) + ex.addExecutor(q.newDataStoreExecutor(meta, subs)); } return ex; } @@ -116,23 +117,19 @@ */ public ResultObjectProvider executeQuery(StoreQuery q, final Object[] params, final Range range) { + ResultObjectProvider[] tmp = new ResultObjectProvider[executors.size()]; + final Iterator<StoreQuery> qs = owner._queries.iterator(); final List<Future<ResultObjectProvider>> futures = new ArrayList<Future<ResultObjectProvider>>(); - List<SliceStoreManager> targets = findTargets(); - for (int i = 0; i < owner._queries.size(); i++) { - StoreQuery query = owner._queries.get(i); - StoreManager sm = owner.getDistributedStore().getSlice(i); - if (!targets.contains(sm)) - continue; + int i = 0; + for (Executor ex:executors) { QueryExecutor call = new QueryExecutor(); - call.executor = executors.get(i); - call.query = query; + call.executor = ex; + call.query = qs.next(); call.params = params; call.range = range; futures.add(threadPool.submit(call)); } - int i = 0; - ResultObjectProvider[] tmp = new ResultObjectProvider[futures.size()]; for (Future<ResultObjectProvider> future:futures) { try { tmp[i++] = future.get(); @@ -213,11 +210,6 @@ } return new Integer(N); } - - List<SliceStoreManager> findTargets() { - FetchConfiguration fetch = owner.getContext().getFetchConfiguration(); - return owner.getDistributedStore().getTargets(fetch); - } }
