From 1679c05c89203f9d8d0c3f1ea1cfdc64943564a5 Mon Sep 17 00:00:00 2001 From: "A. Abram White" Date: Wed, 28 Mar 2007 17:43:35 +0000 Subject: [PATCH] Cleanup and fixes to changes for OPENJPA-168. git-svn-id: https://svn.apache.org/repos/asf/incubator/openjpa/trunk@523425 13f79535-47bb-0310-9956-ffa450edef68 --- .../openjpa/jdbc/kernel/JDBCStoreManager.java | 14 ++-- .../openjpa/jdbc/kernel/JDBCStoreQuery.java | 21 ++---- .../openjpa/jdbc/meta/strats/LRSProxyMap.java | 5 +- .../meta/strats/RelationFieldStrategy.java | 2 +- .../openjpa/jdbc/sql/DB2Dictionary.java | 64 +++---------------- .../apache/openjpa/jdbc/sql/LogicalUnion.java | 48 +++++--------- .../openjpa/jdbc/sql/SelectExecutor.java | 30 ++++----- .../apache/openjpa/jdbc/sql/SelectImpl.java | 51 ++++++--------- .../org/apache/openjpa/kernel/QueryHints.java | 53 +++++++-------- .../org/apache/openjpa/kernel/QueryImpl.java | 11 ++-- .../openjpa/kernel/localizer.properties | 2 +- .../apache/openjpa/persistence/QueryImpl.java | 34 +++++----- .../openjpa/persistence/localizer.properties | 1 + 13 files changed, 123 insertions(+), 213 deletions(-) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java index 0b9809bbd..5c4863952 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreManager.java @@ -43,7 +43,6 @@ import org.apache.openjpa.jdbc.sql.SQLExceptions; import org.apache.openjpa.jdbc.sql.SQLFactory; import org.apache.openjpa.jdbc.sql.Select; import org.apache.openjpa.jdbc.sql.SelectExecutor; -import org.apache.openjpa.jdbc.sql.SelectImpl; import org.apache.openjpa.jdbc.sql.Union; import org.apache.openjpa.kernel.FetchConfiguration; import org.apache.openjpa.kernel.LockManager; @@ -363,17 +362,14 @@ public class JDBCStoreManager * null if there is no data in the current fetch groups to select. */ private Result getInitializeStateResult(OpenJPAStateManager sm, - ClassMapping mapping, JDBCFetchConfiguration fetch, int subs) - throws SQLException { + ClassMapping mapping, JDBCFetchConfiguration fetch, int subs) + throws SQLException { Select sel = _sql.newSelect(); if (!select(sel, mapping, subs, sm, null, fetch, - JDBCFetchConfiguration.EAGER_JOIN, true, false)) + JDBCFetchConfiguration.EAGER_JOIN, true, false)) return null; sel.wherePrimaryKey(sm.getObjectId(), mapping, this); - // Set the expectedResultCount for the select as 1 as a single - // object is being loaded. force = true is an indicator that it is - // internally generated value - sel.setExpectedResultCount(1,true); + sel.setExpectedResultCount(1, false); return sel.execute(this, fetch); } @@ -389,7 +385,7 @@ public class JDBCStoreManager JDBCFetchConfiguration.EAGER_JOIN); Union union = _sql.newUnion(mappings.length); - union.setExpectedResultCount(1,true); + union.setExpectedResultCount(1, false); if (fetch.getSubclassFetchMode(mapping) != fetch.EAGER_JOIN) union.abortUnion(); union.select(new Union.Selector() { diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java index 89798611d..e4b558d40 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/JDBCStoreQuery.java @@ -310,32 +310,25 @@ public class JDBCStoreQuery List selMappings, boolean subclasses, BitSet subclassBits, BitSet nextBits, ExpressionFactory[] facts, QueryExpressions[] exps, QueryExpressionsState[] states, ExpContext ctx, int subclassMode) { + Number optHint = (Number) ctx.fetch.getHint + (QueryHints.HINT_RESULT_COUNT); ClassMapping[] verts; boolean unionable = true; Select sel; - Object optHint = null; for (int i = 0; i < mappings.length; i++) { // determine vertical mappings to select separately verts = getVerticalMappings(mappings[i], subclasses, exps[i], subclassMode); if (verts.length == 1 && subclasses) subclassBits.set(sels.size()); + // create criteria select and clone for each vert mapping sel = ((JDBCExpressionFactory) facts[i]).getSelectConstructor(). evaluate(ctx, null, null, exps[i], states[i]); - // It means it is coming from getSingleResult so set the - // expectedResultCount to 1.force = true indicates that this is - // internally generated value - if (this.ctx.isUnique()) - sel.setExpectedResultCount(1,true); - // It means this is coming from getResultList so set the - // expectedResultCount based on any optimize hint if provided - else { - if ((optHint = ctx.fetch.getHint - (QueryHints.HINT_RESULT_COUNT))!= null) - sel.setExpectedResultCount - (((Integer)optHint).intValue(),false); - } + if (optHint != null) + sel.setExpectedResultCount(optHint.intValue(), true); + else if (this.ctx.isUnique()) + sel.setExpectedResultCount(1, false); for (int j = 0; j < verts.length; j++) { selMappings.add(verts[j]); if (j == verts.length - 1) { diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java index c3a2173dd..91ea0d64e 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/LRSProxyMap.java @@ -236,9 +236,8 @@ class LRSProxyMap final JDBCFetchConfiguration fetch = store.getFetchConfiguration(); final ClassMapping[] clss = _strat.getIndependentValueMappings(true); final Joins[] resJoins = new Joins[Math.max(1, clss.length)]; - Union union = store.getSQLFactory().newUnion - (Math.max(1, clss.length)); - union.setExpectedResultCount(1,true); + Union union = store.getSQLFactory().newUnion(Math.max(1, clss.length)); + union.setExpectedResultCount(1, false); if (fetch.getSubclassFetchMode(_strat.getFieldMapping(). getElementMapping().getTypeMapping()) != JDBCFetchConfiguration.EAGER_JOIN) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java index 9352a17ec..aac23845a 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/meta/strats/RelationFieldStrategy.java @@ -578,7 +578,7 @@ public class RelationFieldStrategy // back to our fk table if not an inverse mapping (in which case we // can just make sure the inverse cols == our pk values) Union union = store.getSQLFactory().newUnion(rels.length); - union.setExpectedResultCount(1,true); + union.setExpectedResultCount(1, false); if (fetch.getSubclassFetchMode(field.getTypeMapping()) != JDBCFetchConfiguration.EAGER_JOIN) union.abortUnion(); diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java index 720bdf344..02a9d7137 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java @@ -28,9 +28,10 @@ import org.apache.openjpa.jdbc.schema.Sequence; */ public class DB2Dictionary extends AbstractDB2Dictionary { - // variables to support optimize clause + public String optimizeClause = "optimize for"; public String rowClause = "row"; + public DB2Dictionary() { platform = "DB2"; validationSQL = "SELECT DISTINCT(CURRENT TIMESTAMP) FROM " @@ -197,60 +198,13 @@ public class DB2Dictionary } } - /** Based on the expectedResultCount of the select create the optimize - * for clause - */ - public String getOptimizeClause(JDBCFetchConfiguration fetch, - int expectedResultCount) { - Integer rows = null; - StringBuffer optimizeString = new StringBuffer(); - if (expectedResultCount != 0) - optimizeString.append(" ").append(optimizeClause).append(" ") - .append(expectedResultCount).append(" ") - .append(rowClause).append(" "); - return optimizeString.toString(); - } - - /** Override the DBDictionary toSelect to call getOptimizeClause and append - * to the select string - */ - public SQLBuffer toSelect(SQLBuffer selects, JDBCFetchConfiguration fetch, - SQLBuffer from, SQLBuffer where, SQLBuffer group, - SQLBuffer having, SQLBuffer order, - boolean distinct, boolean forUpdate, long start, long end, - int expectedResultCount) { - String optimizeString = null; - SQLBuffer selString = toOperation(getSelectOperation(fetch), - selects, from, where, - group, having, order, distinct, - forUpdate, start, end); - if (fetch != null) - optimizeString = getOptimizeClause(fetch, expectedResultCount); - if (optimizeString != null && optimizeString.length() > 0) - selString.append(optimizeString); - return selString; - } - - /** Override the DBDictionary toSelect to pass expectedResultcount to the - * other toSelect method - */ public SQLBuffer toSelect(Select sel, boolean forUpdate, - JDBCFetchConfiguration fetch) { - sel.addJoinClassConditions(); - boolean update = forUpdate && sel.getFromSelect() == null; - SQLBuffer select = getSelects(sel, false, update); - SQLBuffer ordering = null; - if (!sel.isAggregate() || sel.getGrouping() != null) - ordering = sel.getOrdering(); - SQLBuffer from; - if (sel.getFromSelect() != null) - from = getFromSelect(sel, forUpdate); - else - from = getFrom(sel, update); - SQLBuffer where = getWhere(sel, update); - return toSelect(select, fetch, from, where, sel.getGrouping(), - sel.getHaving(), ordering, sel.isDistinct(), forUpdate, - sel.getStartIndex(), - sel.getEndIndex(),sel.getExpectedResultCount()); + JDBCFetchConfiguration fetch) { + SQLBuffer buf = super.toSelect(sel, forUpdate, fetch); + if (sel.getExpectedResultCount() > 0) + buf.append(" ").append(optimizeClause).append(" "). + append(String.valueOf(sel.getExpectedResultCount())). + append(" ").append(rowClause); + return buf; } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java index 7dad3af69..762b4aed1 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/LogicalUnion.java @@ -47,8 +47,7 @@ public class LogicalUnion private static final Localizer _loc = Localizer.forPackage (LogicalUnion.class); - protected int expectedResultCount = 0; - protected boolean force = false; + protected final UnionSelect[] sels; protected final DBDictionary dict; protected final ClassMapping[] mappings; @@ -157,6 +156,16 @@ public class LogicalUnion sels[i].setLRS(lrs); } + public int getExpectedResultCount() { + return sels[0].getExpectedResultCount(); + } + + public void setExpectedResultCount(int expectedResultCount, + boolean force) { + for (int i = 0; i < sels.length; i++) + sels[i].setExpectedResultCount(expectedResultCount, force); + } + public int getJoinSyntax() { return sels[0].getJoinSyntax(); } @@ -208,13 +217,9 @@ public class LogicalUnion return res; } - if (this.getExpectedResultCount()== 1) { + if (getExpectedResultCount() == 1) { AbstractResult res; for (int i = 0; i < sels.length; i++) { - // For each select set the expected result count to 1 - // and force true indicating that this internally generated - // value - sels[i].sel.setExpectedResultCount(1,true); res = (AbstractResult) sels[i].execute(store, fetch, lockLevel); res.setBaseMapping(mappings[i]); @@ -302,8 +307,6 @@ public class LogicalUnion protected final int pos; protected int orders = 0; protected List orderIdxs = null; - protected int expectedResultCount = 0; - protected boolean force = false; public UnionSelect(SelectImpl sel, int pos) { this.sel = sel; @@ -839,17 +842,12 @@ public class LogicalUnion } public int getExpectedResultCount() { - return expectedResultCount; + return sel.getExpectedResultCount(); } - public void setExpectedResultCount(int expectedResultCount, - boolean force) { - this.expectedResultCount = expectedResultCount; - this.force = force; - } - - public boolean isExpRsltCntForced() { - return force; + public void setExpectedResultCount(int expectedResultCount, + boolean force) { + sel.setExpectedResultCount(expectedResultCount, force); } } @@ -931,18 +929,4 @@ public class LogicalUnion return a1.length - a2.length; } } - - public int getExpectedResultCount() { - return expectedResultCount; - } - - public void setExpectedResultCount(int expectedResultCount, - boolean force) { - this.expectedResultCount = expectedResultCount; - this.force = force; - } - - public boolean isExpRsltCntForced() { - return force; - } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java index 1805cc2b2..d3dddf1df 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectExecutor.java @@ -78,6 +78,19 @@ public interface SelectExecutor { * result set. */ public void setLRS(boolean lrs); + + /** + * The expected result count for the query. + */ + public int getExpectedResultCount(); + + /** + * The expected result count for the query. + * + * @param force if false, the count will be discarded if this select has + * any to-many eager joins that would throw off the result count + */ + public void setExpectedResultCount(int expectedResultCount, boolean force); /** * The join syntax for this select, as one of the syntax constants from @@ -119,21 +132,4 @@ public interface SelectExecutor { public Result execute(JDBCStore store, JDBCFetchConfiguration fetch, int lockLevel) throws SQLException; - - /** - * Return the expected result count for the query - */ - public int getExpectedResultCount() ; - - /** - * Set the expected result count for the query - * force indicates whether the count is internally generated - * or given by the user as optimize hint - */ - public void setExpectedResultCount(int expectedResultCount,boolean force) ; - - /** - * Indicates whether the expectedResultCount is internally generated - */ - public boolean isExpRsltCntForced(); } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java index 3654a3593..c118195d6 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SelectImpl.java @@ -82,6 +82,7 @@ public class SelectImpl private static final int EAGER_TO_MANY = 2 << 10; private static final int RECORD_ORDERED = 2 << 11; private static final int GROUPING = 2 << 12; + private static final int FORCE_COUNT = 2 << 13; private static final String[] TABLE_ALIASES = new String[16]; private static final String[] ORDER_ALIASES = new String[16]; @@ -128,6 +129,7 @@ public class SelectImpl private int _nullIds = 0; private int _orders = 0; private int _placeholders = 0; + private int _expectedResultCount = 0; // query clauses private SQLBuffer _ordering = null; @@ -153,9 +155,6 @@ public class SelectImpl // from select if this select selects from a tmp table created by another private SelectImpl _from = null; private SelectImpl _outer = null; - - private int expectedResultCount = 0; - private boolean force = false; /** * Helper method to return the proper table alias for the given alias index. @@ -245,6 +244,22 @@ public class SelectImpl _flags &= ~LRS; } + public int getExpectedResultCount() { + // if the count isn't forced and we have to-many eager joins that could + // throw the count off, don't pay attention to it + if ((_flags & FORCE_COUNT) == 0 && hasEagerJoin(true)) + return 0; + return _expectedResultCount; + } + + public void setExpectedResultCount(int expectedResultCount, boolean force) { + _expectedResultCount = expectedResultCount; + if (force) + _flags |= FORCE_COUNT; + else + _flags &= ~FORCE_COUNT; + } + public int getJoinSyntax() { return _joinSyntax; } @@ -307,20 +322,6 @@ public class SelectImpl JDBCFetchConfiguration fetch, int lockLevel) throws SQLException { boolean forUpdate = false; - - // ExpectedResultCount = 1 and force means that it is internally - // generated value for getSingleResult,single valued relationship. - // We need to check if there are any eager joins in the select if - // there are then the optimize for 1 row clause is not generated - // else we do. if !force then it is set by the user through hint - // and we do not check the eager joins - if (this.expectedResultCount == 1 && force ) { - if (this.hasEagerJoin(true)) - this.setExpectedResultCount(0,false); - else - this.setExpectedResultCount(1,false); - } - if (!isAggregate() && _grouping == null) { JDBCLockManager lm = store.getLockManager(); if (lm != null) @@ -1503,6 +1504,7 @@ public class SelectImpl sel._flags &= ~LRS; sel._flags &= ~EAGER_TO_ONE; sel._flags &= ~EAGER_TO_MANY; + sel._flags &= ~FORCE_COUNT; sel._joinSyntax = _joinSyntax; if (_aliases != null) sel._aliases = new HashMap(_aliases); @@ -1548,6 +1550,7 @@ public class SelectImpl for (int i = 0; i < sels; i++) { sel = (SelectImpl) whereClone(1); sel._flags = _flags; + sel._expectedResultCount = _expectedResultCount; sel._selects.addAll(_selects); if (_ordering != null) sel._ordering = new SQLBuffer(_ordering); @@ -2816,20 +2819,6 @@ public class SelectImpl _idents = null; } } - - public int getExpectedResultCount() { - return expectedResultCount; - } - - public void setExpectedResultCount(int expectedResultCount, - boolean force) { - this.expectedResultCount = expectedResultCount; - this.force = force; - } - - public boolean isExpRsltCntForced() { - return force; - } } /** diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java index fd9623a7c..80b1c796b 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java @@ -1,25 +1,28 @@ -/* - * Copyright 2006 The Apache Software Foundation. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.openjpa.kernel; - -public interface QueryHints { - - /** Hint to specify the number of rows for the optimize - * clause for DB2 - */ - public static final String HINT_RESULT_COUNT = - "openjpa.hint.OptimizeResultCount"; -} +/* + * Copyright 2006 The Apache Software Foundation. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.openjpa.kernel; + +/** + * Standard query hint keys. + */ +public interface QueryHints { + + /** + * Hint to specify the number of rows to optimize for. + */ + public static final String HINT_RESULT_COUNT = + "openjpa.hint.OptimizeResultCount"; +} diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java index 9e4aa3279..be23214de 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryImpl.java @@ -1273,14 +1273,17 @@ public class QueryImpl boolean next = rop.next(); // extract single result; throw an exception if multiple results - // match and not constrainted by range, as per spec + // match and not constrainted by range, or if a unique query with + // no results Object single = null; if (next) { single = rop.getResultObject(); if (range.end != range.start + 1 && rop.next()) throw new InvalidStateException(_loc.get("not-unique", _class, _query)); - } + } else if (_unique == Boolean.TRUE) + throw new InvalidStateException(_loc.get("no-result", + _class, _query)); // if unique set to false, use collection if (_unique == Boolean.FALSE) { @@ -1289,10 +1292,6 @@ public class QueryImpl // Collections.singletonList is JDK 1.3, so... return Arrays.asList(new Object[]{ single }); } - - if (single == null) - throw new InvalidStateException(_loc.get("is-null", - _class, _query)); // return single result return single; diff --git a/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties b/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties index 6e6fab82d..e9e8ab50c 100644 --- a/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties +++ b/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/localizer.properties @@ -259,7 +259,7 @@ executing-query-with-params: Executing query: [{0}] with parameters: {1} not-unique: The query on candidate type "{0}" with filter "{1}" was \ configured to have a unique result, but more than one instance matched \ the query. -is-null: The query on candidate type "{0}" with filter "{1}" was \ +no-result: The query on candidate type "{0}" with filter "{1}" was \ configured to have a unique result, but no instance matched \ the query. serialized: Queries that have been serialized do not support this operation. diff --git a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java index 8f5a37d8d..44565ff56 100644 --- a/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java +++ b/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java @@ -279,12 +279,12 @@ public class QueryImpl */ public Object getSingleResult() { _em.assertNotCloseInvoked(); - // Indicate that this query returns single result.Later copied into - // select.expectedResultCount + // temporarily set query to unique so that a single result is validated + // and returned; unset again in case the user executes query again + // via getResultList _query.setUnique(true); try { - Object ob = execute(); - return ob; + return execute(); } finally { _query.setUnique(false); } @@ -367,16 +367,17 @@ public class QueryImpl Filters.hintToSetter(getFetchPlan(), k, value); } else if (k.startsWith("hint.")) { if ("hint.OptimizeResultCount".equals(k)) { - if ((!(value instanceof String)&&! (value instanceof Integer)) - || (value instanceof String &&(Integer.parseInt - ((String)value)< 0))|| - ((value instanceof Integer) - && (((Integer)value).intValue()<0))) + if (value instanceof String) { + try { + value = new Integer((String) value); + } catch (NumberFormatException nfe) { + } + } + if (!(value instanceof Number) + || ((Number) value).intValue() < 0) throw new ArgumentException(_loc.get - ("bad-hint-value", key), - null, null, false); - if (value instanceof String) - value = new Integer((String)value); + ("bad-query-hint-value", key, value), null, null, + false); } _query.getFetchConfiguration().setHint(key, value); } @@ -384,12 +385,7 @@ public class QueryImpl throw new ArgumentException(_loc.get("bad-query-hint", key), null, null, false); return this; - } - catch (NumberFormatException e1) { - throw new ArgumentException(_loc.get("bad-hint-value", key), - null, null, false); - } - catch (Exception e) { + } catch (Exception e) { throw PersistenceExceptions.toPersistenceException(e); } } diff --git a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties index fabc4e113..1601f8f3c 100644 --- a/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties +++ b/openjpa-persistence/src/main/resources/org/apache/openjpa/persistence/localizer.properties @@ -64,6 +64,7 @@ mult-results: Query returned multiple results: "{0}". no-pos-named-params-mix: Cannot mix named and positional parameters in query \ "{0}". bad-query-hint: "{0}" is not a recognized query hint. +bad-query-hint-value: Invalid value specified for query hint "{0}": {1} detached: Cannot perform this operation on detached entity "{0}". removed: Cannot perform this operation on removed entity "{0}". bad-alias: There is no known entity class for entity name "{0}". It is \