OPENJPA-1013: Add tests for multiselect()

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@799432 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2009-07-30 19:56:52 +00:00
parent 9706a82960
commit 3ae614fc26
3 changed files with 287 additions and 2 deletions

View File

@ -59,8 +59,8 @@ public abstract class CriteriaTest extends TestCase {
protected static OpenJPAEntityManagerFactorySPI emf;
protected static SQLAuditor auditor;
CriteriaBuilder cb;
EntityManager em;
protected CriteriaBuilder cb;
protected EntityManager em;
protected static Class[] CLASSES = {
Account.class,

View File

@ -38,6 +38,14 @@ public class Person {
@ElementCollection
private Set<String> nickNames;
protected Person() {
this("?");
}
public Person(String name) {
setName(name);
}
public int getId() {
return id;

View File

@ -0,0 +1,277 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.persistence.criteria.results;
import java.lang.reflect.Array;
import java.util.List;
import javax.persistence.PersistenceException;
import javax.persistence.Tuple;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.apache.openjpa.persistence.criteria.CriteriaTest;
import org.apache.openjpa.persistence.criteria.Person;
import org.apache.openjpa.persistence.criteria.Person_;
import org.apache.openjpa.persistence.test.AllowFailure;
/**
* Test variations of {@link CriteriaQuery#multiselect(java.util.List)} arguments.
*
* @author Pinaki Poddar
*
*/
@AllowFailure(value=true, message="Tests:16 Errors:1 Failure:7")
public class TestMultiselect extends CriteriaTest {
private static final Class[] CLASSES = {Person.class};
private static boolean initialized = false;
@Override
public void setUp() {
super.setUp();
if (!initialized) {
createData();
initialized = true;
}
}
@Override
protected Class[] getDomainClasses() {
return CLASSES;
}
void createData() {
em.getTransaction().begin();
Person p = new Person("Test Result Shape");
em.persist(p);
em.getTransaction().commit();
}
/**
* If the type of the criteria query is CriteriaQuery<Tuple>
* (i.e., a criteria query object created by either the
* createTupleQuery method or by passing a Tuple class argument
* to the createQuery method), a Tuple object corresponding to
* the elements of the list passed to the multiselect method
* will be instantiated and returned for each row that results
* from the query execution.
* */
public void testTupleQuery() {
CriteriaQuery<Tuple> q = cb.createTupleQuery();
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name), p.get(Person_.id));
assertResult(q, Tuple.class);
}
public void testTupleQueryExplicit() {
CriteriaQuery<Tuple> q = cb.createQuery(Tuple.class);
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name), p.get(Person_.id));
assertResult(q, Tuple.class);
}
//=======================================================================
/**
* If the type of the criteria query is CriteriaQuery<X> for
* some user-defined class X (i.e., a criteria query object
* created by passing a X class argument to the createQuery
* method), then the elements of the list passed to the
* multiselect method will be passed to the X constructor and
* an instance of type X will be returned for each row.
*/
public void testUserResultQueryWithExplictProjectionOfConstructorArguments() {
CriteriaQuery<Person> q = cb.createQuery(Person.class);
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name));
assertResult(q, Person.class);
}
public void testUserResultQueryWithImplicitProjection() {
CriteriaQuery<Person> q = cb.createQuery(Person.class);
Root<Person> p = q.from(Person.class);
assertResult(q, Person.class);
}
public void testUserResultQueryWithMismatchProjectionOfConstructorArguments() {
CriteriaQuery<Person> q = cb.createQuery(Person.class);
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name), p.get(Person_.id));
fail("Person has no constrcutor with (name,id)", q);
}
// ======================================================================
/**
* If the type of the criteria query is CriteriaQuery<X[]> for
* some class X, an instance of type X[] will be returned for
* each row. The elements of the array will correspond to the
* elements of the list passed to the multiselect method.
*/
public void testUserClassArray() {
CriteriaQuery<Person[]> q = cb.createQuery(Person[].class);
Root<Person> p = q.from(Person.class);
q.multiselect(p,p);
assertResult(q, Person[].class, Person.class, Person.class);
}
public void testBasicClassArray() {
CriteriaQuery<String[]> q = cb.createQuery(String[].class);
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name), p.get(Person_.name));
assertResult(q, String[].class);
}
public void testTupleArray() {
CriteriaQuery<Tuple[]> q = cb.createQuery(Tuple[].class);
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name), p.get(Person_.name));
assertResult(q, Tuple[].class);
}
// =================================================================
/**
* If the type of the criteria query is CriteriaQuery<Object>
* or if the criteria query was created without specifying a
* type, and the list passed to the multiselect method contains
* only a single element, an instance of type Object will be
* returned for each row.
*/
public void testSingleObject() {
CriteriaQuery<Object> q = cb.createQuery(Object.class);
Root<Person> p = q.from(Person.class);
q.multiselect(p);
assertResult(q, Object.class);
}
public void testSingleObjectViaConstructor() {
CriteriaQuery<Object> q = cb.createQuery(Object.class);
Root<Person> p = q.from(Person.class);
q.multiselect(cb.construct(Person.class, p.get(Person_.name)));
assertResult(q, Object.class);
}
public void testSingleObjectAsProperty() {
CriteriaQuery<Object> q = cb.createQuery(Object.class);
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name));
assertResult(q, Object.class);
}
public void testSingleObjectImplicit() {
CriteriaQuery<?> q = cb.createQuery();
Root<Person> p = q.from(Person.class);
q.multiselect(p);
assertResult(q, Object.class);
}
public void testSingleObjectViaConstructorImplicit() {
CriteriaQuery<?> q = cb.createQuery();
Root<Person> p = q.from(Person.class);
q.multiselect(cb.construct(Person.class, p.get(Person_.name)));
assertResult(q, Object.class);
}
public void testSingleObjectAsPropertyImplicit() {
CriteriaQuery<?> q = cb.createQuery();
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name));
assertResult(q, Object.class);
}
// ================================================================================
/**
* If the type of the criteria query is CriteriaQuery<Object>
* or if the criteria query was created without specifying a
* type, and the list passed to the multiselect method contains
* more than one element, an instance of type Object[] will be
* instantiated and returned for each row. The elements of the
* array will correspond to the elements of the list passed to
* the multiselect method.
*/
public void testSingleObjectMultipleProjections() {
CriteriaQuery<Object> q = cb.createQuery(Object.class);
Root<Person> p = q.from(Person.class);
q.multiselect(p.get(Person_.name), p.get(Person_.id));
assertResult(q, Object[].class, String.class, Integer.class);
}
public void testSingleObjectMultipleProjectionsAndConstructor() {
CriteriaQuery<Object> q = cb.createQuery(Object.class);
Root<Person> p = q.from(Person.class);
q.multiselect(cb.construct(Person.class, p.get(Person_.name)), p.get(Person_.id), p.get(Person_.name));
assertResult(q, Object[].class, Person.class, Integer.class, String.class);
}
/**
* An element of the list passed to the multiselect method
* must not be a tuple- or array-valued compound selection item.
*/
// =============== assertions by result types ========================
void assertResult(CriteriaQuery<?> q, Class<?> resultClass) {
assertResult(q, resultClass, (Class<?>[])null);
}
/**
* Assert the query result elements by their types
*/
void assertResult(CriteriaQuery<?> q, Class<?> resultClass, Class<?>... arrayElementClasses) {
List<?> result = em.createQuery(q).getResultList();
assertFalse(result.isEmpty());
for (Object row : result) {
assertTrue(row.getClass() + " does not match actual result " + resultClass, resultClass.isInstance(row));
if (resultClass.isArray() && arrayElementClasses != null) {
for (int i = 0; i < arrayElementClasses.length; i++) {
Object element = Array.get(row, i);
assertTrue(i + "-th array element " + arrayElementClasses[i] + " does not match actual result "
+ element.getClass(), arrayElementClasses[i].isInstance(element));
}
}
}
}
void fail(String msg, CriteriaQuery<?> q) {
try {
em.createQuery(q).getResultList();
fail("Expected to fail " + msg);
} catch (PersistenceException e) {
// this is an expected exception
}
}
}