OPENJPA-1225: Fail fast on wrong constructor() argument

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@808513 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2009-08-27 16:53:50 +00:00
parent 39da6319dd
commit 6305be480b
3 changed files with 45 additions and 2 deletions

View File

@ -379,6 +379,26 @@ public class TestMultiselect extends CriteriaTest {
assertEquals(String.class, tuple4.get(0).getClass());
}
public void testConstructorFailsFast() {
CriteriaQuery<Tuple> q = cb.createQuery(Tuple.class);
Root<Foo> foo = q.from(Foo.class);
try {
q.multiselect(cb.construct(Foo.class, foo.get(Foo_.flong)));
fail("Expected IllegalArgumentException becuase Foo(long) is not a valid constructor");
} catch (IllegalArgumentException e) {
// good -- but print the error message to check it is informative enough
System.err.println(e);
}
try {
q.multiselect(cb.construct(Foo.class));
fail("Expected IllegalArgumentException becuase Foo() is not a valid constructor");
} catch (IllegalArgumentException e) {
// good -- but print the error message to check it is informative enough
System.err.println(e);
}
}
// =============== assertions by result types ========================
void assertResult(CriteriaQuery<?> q, Class<?> resultClass) {

View File

@ -18,6 +18,7 @@
*/
package org.apache.openjpa.persistence.criteria;
import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@ -30,6 +31,7 @@ import javax.persistence.criteria.Selection;
import org.apache.openjpa.kernel.FillStrategy;
import org.apache.openjpa.kernel.ResultShape;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.persistence.TupleFactory;
import org.apache.openjpa.persistence.TupleImpl;
@ -42,6 +44,7 @@ import org.apache.openjpa.persistence.TupleImpl;
*
*/
public class CompoundSelections {
private static Localizer _loc = Localizer.forPackage(CompoundSelections.class);
/**
* Gets the strategy to fill a given compound selection.
*
@ -118,12 +121,29 @@ public class CompoundSelections {
* @param <X> type of the constructed instance
*/
public static class NewInstance<X> extends CompoundSelectionImpl<X> {
private FillStrategy.NewInstance<X> strategy;
public NewInstance(Class<X> cls, Selection<?>... selections) {
super(cls, selections);
strategy = new FillStrategy.NewInstance<X>(findConstructor(cls, selections));
}
public FillStrategy<X> getFillStrategy() {
return new FillStrategy.NewInstance<X>(getJavaType());
return strategy;
}
private Constructor<X> findConstructor(Class<X> cls, Selection<?>... selections) {
Class<?>[] types = selections == null ? null : new Class[selections.length];
if (selections != null) {
for (int i = 0; i < selections.length; i++) {
types[i] = selections[i].getJavaType();
}
}
try {
return cls.getConstructor(types);
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException(_loc.get("select-no-ctor", cls,
types == null ? "[]" : Arrays.toString(types)).getMessage());
}
}
}

View File

@ -21,4 +21,7 @@ root-undefined: No root is defined for criteria query. \
Use CriteriaQuery.from(Class) to define a root.
select-undefined: No terms is selected for criteria query. \
Use CriteriaQuery.select() or multiselect() to select \
projection terms for the query.
projection terms for the query.
select-no-ctor: You have specified selection term to construct an instance of \
"{0}" with argument types "{1}". But "{0}" has no constructor with such \
argument types.