blob: 40ff3e525453b5bd704ffa467234f361b0d9854b [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// July 22, 2009-2.0 Chris Delahunt
// - TODO Bug#: Bug Description
package org.eclipse.persistence.testing.tests.jpa.criteria;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.Iterator;
import org.junit.Assert;
import junit.framework.Test;
import junit.framework.TestSuite;
import jakarta.persistence.Query;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Tuple;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.ParameterExpression;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Subquery;
import jakarta.persistence.metamodel.EntityType;
import org.eclipse.persistence.expressions.Expression;
import org.eclipse.persistence.expressions.ExpressionBuilder;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.mappings.DirectToFieldMapping;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.queries.ReportQuery;
import org.eclipse.persistence.queries.ReportQueryResult;
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.testing.models.jpa.advanced.Address;
import org.eclipse.persistence.testing.models.jpa.advanced.AdvancedTableCreator;
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.advanced.Project;
import org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber;
import org.eclipse.persistence.testing.tests.jpa.advanced.DataHolder;
import org.eclipse.persistence.testing.tests.jpa.jpql.*;
/**
* <p>
* <b>Purpose</b>: Test Unit Criteria API functionality.
* <p>
* <b>Description</b>: This class creates a test suite, initializes the database
* and adds tests to the suite.
* <p>
* <b>Responsibilities</b>:
* <ul>
* <li> Run tests for Criteria API functionality
* </ul>
* @see org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator
* @see JUnitDomainObjectComparer
* @see JUnitJPQLUnitTestSuite
*/
//This test suite demonstrates the bug 4616218, waiting for bug fix
public class JUnitCriteriaUnitTestSuite extends JUnitTestCase
{
static JUnitDomainObjectComparer comparer;
public JUnitCriteriaUnitTestSuite()
{
super();
}
public JUnitCriteriaUnitTestSuite(String name)
{
super(name);
}
//This method is run at the end of EVERY test case method
@Override
public void tearDown()
{
clearCache();
}
//This suite contains all tests contained in this class
public static Test suite()
{
TestSuite suite = new TestSuite();
suite.setName("JUnitCriteriaUnitTestSuite");
suite.addTest(new JUnitCriteriaUnitTestSuite("testSetup"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testExistWithJoin"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testSelectPhoneNumberAreaCode"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testSelectPhoneNumberAreaCodeWithEmployee"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testSelectPhoneNumberNumberWithEmployeeWithExplicitJoin"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testSelectPhoneNumberNumberWithEmployeeWithFirstNameFirst"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testSelectEmployeeWithSameParameterUsedMultipleTimes"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testOuterJoinOnOneToOne"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testOuterJoinPolymorphic"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testFirstResult"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testInvertedSelectionCriteriaNullPK"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testInvertedSelectionCriteriaInvalidQueryKey"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testMaxAndFirstResultsOnDataQuery"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testMaxAndFirstResultsOnDataQueryWithGroupBy"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testMaxAndFirstResultsOnObjectQueryOnInheritanceRoot"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testDistinctSelectForEmployeeWithNullAddress"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testConstructorWithFunctionParameters"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testNonExistentConstructorCriteriaQuery"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testIsNullAndIsNotNull"));
suite.addTest(new JUnitCriteriaUnitTestSuite("testIsNullOrIsNull"));
return suite;
}
/**
* The setup is done as a test, both to record its failure, and to allow execution in the server.
*/
public void testSetup() {
clearCache();
//get session to start setup
DatabaseSession session = JUnitTestCase.getServerSession();
//create a new EmployeePopulator
EmployeePopulator employeePopulator = new EmployeePopulator();
new AdvancedTableCreator().replaceTables(session);
//initialize the global comparer object
comparer = new JUnitDomainObjectComparer();
//set the session for the comparer to use
comparer.setSession((AbstractSession)session.getActiveSession());
//Populate the tables
employeePopulator.buildExamples();
//Persist the examples in the database
employeePopulator.persistExample(session);
}
public Vector getAttributeFromAll(String attributeName, Vector objects, Class referenceClass) {
ClassDescriptor descriptor = getServerSession().getClassDescriptor(referenceClass);
DirectToFieldMapping mapping = (DirectToFieldMapping)descriptor.getMappingForAttributeName(attributeName);
Vector attributes = new Vector();
Object currentObject;
for(int i = 0; i < objects.size(); i++) {
currentObject = objects.elementAt(i);
if(currentObject.getClass() == ReportQueryResult.class) {
attributes.addElement(
((ReportQueryResult)currentObject).get(attributeName));
} else {
attributes.addElement(
mapping.getAttributeValueFromObject(currentObject));
}
}
return attributes;
}
public void testFirstResult(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
clearCache();
//SELECT OBJECT(employee) FROM Employee employee WHERE employee.firstName = :firstname
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> from = cq.from(Employee.class);
cq.where(qb.equal(from.get("firstName"), qb.parameter(String.class, "firstname")));
Query query = em.createQuery(cq);
List initialList = query.setParameter("firstname", "Nancy").setFirstResult(0).getResultList();
List secondList = query.setParameter("firstname", "Nancy").setFirstResult(1).getResultList();
Iterator i = initialList.iterator();
while (i.hasNext()){
assertTrue("Employee with incorrect name returned on first query.", ((Employee)i.next()).getFirstName().equals("Nancy"));
}
i = secondList.iterator();
while (i.hasNext()){
assertTrue("Employee with incorrect name returned on second query.", ((Employee)i.next()).getFirstName().equals("Nancy"));
}
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
//done upto here
public void testOuterJoinOnOneToOne(){
EntityManager em = createEntityManager();
clearCache();
beginTransaction(em);
//"SELECT e from Employee e JOIN e.address a"
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
cq.from(Employee.class).join("address");
cq.distinct(true);
int initialSize = em.createQuery(cq).getResultList().size();
Employee emp = new Employee();
emp.setFirstName("Steve");
emp.setLastName("Harp");
em.persist(emp);
em.flush();
//"SELECT e from Employee e LEFT OUTER JOIN e.address a"
qb = em.getCriteriaBuilder();
cq = qb.createQuery(Employee.class);
cq.from(Employee.class).join("address", JoinType.LEFT);
cq.distinct(true);
List<Employee> result = em.createQuery(cq).getResultList();
assertTrue("Outer join was not properly added to the query", initialSize + 1 == result.size());
rollbackTransaction(em);
}
public void testOuterJoinPolymorphic(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
clearCache();
List resultList = null;
try{
resultList = em.createQuery(em.getCriteriaBuilder().createQuery(Project.class)).getResultList();
} catch (Exception exception){
fail("Exception caught while executing polymorphic query. This may mean that outer join is not working correctly on your database platfrom: " + exception.toString());
}
assertTrue("Incorrect number of projects returned.", resultList.size() == 15);
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
//This test case demonstrates the bug 4616218
public void testSelectPhoneNumberAreaCode()
{
ExpressionBuilder employeeBuilder = new ExpressionBuilder();
Expression phones = employeeBuilder.anyOf("phoneNumbers");
Expression whereClause = phones.get("areaCode").equal("613");
ReportQuery rq = new ReportQuery();
rq.setSelectionCriteria(whereClause);
rq.addAttribute("areaCode", new ExpressionBuilder().anyOf("phoneNumbers").get("areaCode"));
rq.setReferenceClass(Employee.class);
rq.dontUseDistinct(); // distinct no longer used on joins in JPQL for gf bug 1395
EntityManager em = createEntityManager();
beginTransaction(em);
try{
Vector expectedResult = getAttributeFromAll("areaCode", (Vector)getServerSession().executeQuery(rq),Employee.class);
clearCache();
//List result = em.createQuery("SELECT phone.areaCode FROM Employee employee, IN (employee.phoneNumbers) phone " +
// "WHERE phone.areaCode = \"613\"").getResultList();
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<String> cq = qb.createQuery(String.class);
Root<Employee> root = cq.from(Employee.class);
Join<Object, Object> phone = root.join("phoneNumbers");
cq.select(phone.get("areaCode"));
cq.where(qb.equal(phone.get("areaCode"), "613"));
List<String> result = em.createQuery(cq).getResultList();
Assert.assertTrue("SimpleSelectPhoneNumberAreaCode test failed !", comparer.compareObjects(result,expectedResult));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testExistWithJoin()
{
EntityManager em = createEntityManager();
List expected = em.createQuery("SELECT c FROM Employee c WHERE NOT EXISTS (SELECT o1 FROM c.phoneNumbers o1)").getResultList();
beginTransaction(em);
try {
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery =qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
cquery.select(customer);
Subquery<PhoneNumber> sq = cquery.subquery(PhoneNumber.class);
// correlate subquery root to root of main query:
Root<Employee> sqc = sq.correlate(customer);
Join<Employee, PhoneNumber> sqo = sqc.join("phoneNumbers");
sq.select(sqo);
cquery.where(qbuilder.not(qbuilder.exists(sq)));
List<Employee> result = em.createQuery(cquery).getResultList();
Assert.assertTrue("testExistWithJoin test failed !", comparer.compareObjects(result,expected));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSelectPhoneNumberAreaCodeWithEmployee()
{
EntityManager em = createEntityManager();
beginTransaction(em);
try{
ExpressionBuilder employees = new ExpressionBuilder();
Expression exp = employees.get("firstName").equal("Bob");
exp = exp.and(employees.get("lastName").equal("Smith"));
Employee emp = (Employee) getServerSession().readAllObjects(Employee.class, exp).firstElement();
PhoneNumber phone = (PhoneNumber) ((Vector)emp.getPhoneNumbers()).firstElement();
String areaCode = phone.getAreaCode();
String firstName = emp.getFirstName();
ExpressionBuilder employeeBuilder = new ExpressionBuilder();
Expression phones = employeeBuilder.anyOf("phoneNumbers");
Expression whereClause = phones.get("areaCode").equal(areaCode).and(
phones.get("owner").get("firstName").equal(firstName));
ReportQuery rq = new ReportQuery();
rq.setSelectionCriteria(whereClause);
rq.addAttribute("areaCode", phones.get("areaCode"));
rq.setReferenceClass(Employee.class);
rq.dontMaintainCache();
Vector expectedResult = getAttributeFromAll("areaCode", (Vector)getServerSession().executeQuery(rq),Employee.class);
clearCache();
//"SELECT phone.areaCode FROM Employee employee, IN (employee.phoneNumbers) phone " +
// "WHERE phone.areaCode = \"" + areaCode + "\" AND phone.owner.firstName = \"" + firstName + "\"";
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<String> cq = qb.createQuery(String.class);
Root<Employee> root = cq.from(Employee.class);
Join<Object, Object> joinedPhone = root.join("phoneNumbers");
cq.select(joinedPhone.get("areaCode"));
cq.where(qb.and(qb.equal(joinedPhone.get("areaCode"), "613")), qb.equal(joinedPhone.get("owner").get("firstName"), firstName));
List<String> result = em.createQuery(cq).getResultList();
Assert.assertTrue("SimpleSelectPhoneNumberAreaCodeWithEmployee test failed !", comparer.compareObjects(result,expectedResult));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSelectPhoneNumberNumberWithEmployeeWithExplicitJoin()
{
EntityManager em = createEntityManager();
beginTransaction(em);
try{
ExpressionBuilder employees = new ExpressionBuilder();
Expression exp = employees.get("firstName").equal("Bob");
exp = exp.and(employees.get("lastName").equal("Smith"));
Employee emp = (Employee) getServerSession().readAllObjects(Employee.class, exp).firstElement();
PhoneNumber phone = (PhoneNumber) ((Vector)emp.getPhoneNumbers()).firstElement();
String areaCode = phone.getAreaCode();
String firstName = emp.getFirstName();
ExpressionBuilder employeeBuilder = new ExpressionBuilder(Employee.class);
Expression phones = employeeBuilder.anyOf("phoneNumbers");
Expression whereClause = phones.get("areaCode").equal(areaCode).and(
phones.get("owner").get("id").equal(employeeBuilder.get("id")).and(
employeeBuilder.get("firstName").equal(firstName)));
ReportQuery rq = new ReportQuery();
rq.addAttribute("number", new ExpressionBuilder().anyOf("phoneNumbers").get("number"));
rq.setSelectionCriteria(whereClause);
rq.setReferenceClass(Employee.class);
Vector expectedResult = getAttributeFromAll("number", (Vector)getServerSession().executeQuery(rq),Employee.class);
clearCache();
//"SELECT phone.number FROM Employee employee, IN (employee.phoneNumbers) phone " +
// "WHERE phone.areaCode = \"" + areaCode + "\" AND (phone.owner.id = employee.id AND employee.firstName = \"" + firstName + "\")";
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<String> cq = qb.createQuery(String.class);
Root<Employee> root = cq.from(Employee.class);
Join<Object, Object> joinedPhone = root.join("phoneNumbers");
cq.select(joinedPhone.get("number"));
//cq.where(qb.equal(joinedPhone.get("areaCode"), areaCode).add(qb.equal(joinedPhone.get("owner").get("id"), root.get("id"))).add(qb.equal(root.get("firstName"), firstName)));
Predicate firstAnd = qb.and(qb.equal(joinedPhone.get("areaCode"), areaCode), qb.equal(joinedPhone.get("owner").get("id"), root.get("id")));
cq.where(qb.and( firstAnd, qb.equal(root.get("firstName"), firstName)));
List<String> result = em.createQuery(cq).getResultList();
Assert.assertTrue("SimpleSelectPhoneNumberAreaCodeWithEmployee test failed !", comparer.compareObjects(result,expectedResult));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSelectPhoneNumberNumberWithEmployeeWithFirstNameFirst()
{
EntityManager em = createEntityManager();
beginTransaction(em);
try{
ExpressionBuilder employees = new ExpressionBuilder();
Expression exp = employees.get("firstName").equal("Bob");
exp = exp.and(employees.get("lastName").equal("Smith"));
Employee emp = (Employee) getServerSession().readAllObjects(Employee.class, exp).firstElement();
PhoneNumber phone = (PhoneNumber) ((Vector)emp.getPhoneNumbers()).firstElement();
String areaCode = phone.getAreaCode();
String firstName = emp.getFirstName();
ExpressionBuilder employeeBuilder = new ExpressionBuilder();
Expression phones = employeeBuilder.anyOf("phoneNumbers");
Expression whereClause = phones.get("owner").get("firstName").equal(firstName).and(
phones.get("areaCode").equal(areaCode));
ReportQuery rq = new ReportQuery();
rq.setSelectionCriteria(whereClause);
rq.addAttribute("number", phones.get("number"));
rq.setReferenceClass(Employee.class);
Vector expectedResult = getAttributeFromAll("number", (Vector)getServerSession().executeQuery(rq),Employee.class);
clearCache();
//"SELECT phone.number FROM Employee employee, IN(employee.phoneNumbers) phone " +
// "WHERE phone.owner.firstName = \"" + firstName + "\" AND phone.areaCode = \"" + areaCode + "\"";
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<String> cq = qb.createQuery(String.class);
Root<Employee> root = cq.from(Employee.class);
Join<Object, Object> joinedPhone = root.join("phoneNumbers");
cq.select(joinedPhone.get("number"));
Predicate firstNameEquality = qb.equal(joinedPhone.get("owner").get("firstName"), firstName);
Predicate areaCodeEquality =qb.equal(joinedPhone.get("areaCode"), areaCode);
cq.where( qb.and(firstNameEquality, areaCodeEquality) );
List<String> result = em.createQuery(cq).getResultList();
Assert.assertTrue("SimpleSelectPhoneNumberAreaCodeWithEmployee test failed !", comparer.compareObjects(result,expectedResult));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSelectEmployeeWithSameParameterUsedMultipleTimes() {
Exception exception = null;
try {
EntityManager em = createEntityManager();
beginTransaction(em);
try{
//"SELECT emp FROM Employee emp WHERE emp.id > :param1 OR :param1 IS null";
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> root = cq.from(Employee.class);
ParameterExpression<Integer> param1 = qb.parameter(Integer.class);
//need to cast to erase the type on the get("id") expression so it matches the type on param1
cq.where(qb.or( qb.greaterThan(root.<Integer>get("id" ), param1), param1.isNull()) );
em.createQuery(cq).setParameter(param1, 1).getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
} catch (Exception e) {
exception = e;
}
Assert.assertNull("Exception was caught.", exception);
}
/**
* Prior to the fix for GF 2333, the query in this test would a Null PK exception
*
*/
public void testInvertedSelectionCriteriaNullPK() {
EntityManager em = createEntityManager();
beginTransaction(em);
try{
//"SELECT e, p FROM Employee e, PhoneNumber p WHERE p.id = e.id AND e.firstName = 'Bob'"
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = qb.createTupleQuery();
Root<Employee> rootEmp = cq.from(Employee.class);
Root<PhoneNumber> rootPhone = cq.from(PhoneNumber.class);
cq.multiselect(rootEmp, rootPhone);
cq.where(qb.and( qb.equal(rootPhone.get("id"), rootEmp.get("id")), qb.equal(rootEmp.get("firstName"), "Bob")) );
em.createQuery(cq).getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Tests fix for bug6070214 that using Oracle Rownum pagination with non-unique columns
* throws an SQl exception.
*/
public void testMaxAndFirstResultsOnDataQuery(){
Exception exception = null;
List resultList = null;
EntityManager em = createEntityManager();
beginTransaction(em);
try{
clearCache();
//"SELECT e.id, m.id FROM Employee e LEFT OUTER JOIN e.manager m"
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = qb.createTupleQuery();
Root<Employee> rootEmp = cq.from(Employee.class);
Join<Object, Object> joinedManager = rootEmp.join("manager", JoinType.LEFT);
cq.multiselect(rootEmp.get("id"), joinedManager.get("id"));
Query query = em.createQuery(cq);
try {
query.setFirstResult(1);
query.setMaxResults(1);
resultList = query.getResultList();
} catch (Exception e) {
logThrowable(exception);
exception = e;
}
Assert.assertNull("Exception was caught: " + exception, exception);
Assert.assertTrue("Incorrect number of results returned. Expected 1, returned "+resultList.size(), resultList.size()==1);
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Tests fix for bug6070214 that using Oracle Rownum pagination with group by
* throws an SQl exception.
*/
public void testMaxAndFirstResultsOnDataQueryWithGroupBy() {
Exception exception = null;
List resultList = null;
EntityManager em = createEntityManager();
beginTransaction(em);
try{
clearCache();
//"SELECT e.id FROM Employee e group by e.id"
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Integer> cq = qb.createQuery(Integer.class);
Root<Employee> rootEmp = cq.from(Employee.class);
Join<Object, Object> joinedManager = rootEmp.join("manager", JoinType.LEFT);
cq.select(rootEmp.get("id"));
Query query = em.createQuery(cq);
try {
query.setFirstResult(1);
query.setMaxResults(1);
resultList = query.getResultList();
} catch (Exception e) {
logThrowable(exception);
exception = e;
}
Assert.assertNull("Exception was caught: " + exception, exception);
Assert.assertTrue("Incorrect number of results returned. Expected 1, returned "+resultList.size(), resultList.size()==1);
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Tests fix for bug 253258 that using filtering using MaxResults/FirstResult returns
* the correct number of results on an inheritance root class.
*/
public void testMaxAndFirstResultsOnObjectQueryOnInheritanceRoot() {
Exception exception = null;
List resultList = null;
EntityManager em = createEntityManager();
beginTransaction(em);
try{
clearCache();
//"SELECT p FROM Project p"
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Project> cq = qb.createQuery(Project.class);
Query query = em.createQuery(cq);
try {
query.setFirstResult(6);
query.setMaxResults(1);
resultList = query.getResultList();
} catch (Exception e) {
exception = e;
logThrowable(exception);
}
Assert.assertNull("Exception was caught.", exception);
Assert.assertTrue("Incorrect number of results returned. Expected 1, returned "+resultList.size(), resultList.size()==1);
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Prior to the fix for GF 2333, the query in this test would generate an invalid query key exception
*
*/
public void testInvertedSelectionCriteriaInvalidQueryKey(){
Exception exception = null;
try {
EntityManager em = createEntityManager();
beginTransaction(em);
try{
//"select e, a from Employee e, Address a where a.city = 'Ottawa' and e.address.country = a.country"
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = qb.createTupleQuery();
Root<Employee> rootEmp = cq.from(Employee.class);
Root<Address> rootAddress = cq.from(Address.class);
cq.multiselect(rootEmp, rootAddress);
cq.where(qb.and( qb.equal(rootAddress.get("city"), "Ottawa"), qb.equal(rootEmp.get("address").get("country"), rootAddress.get("country"))));
List<Tuple> resultList = em.createQuery(cq).getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
} catch (Exception e) {
logThrowable(e);
exception = e;
}
Assert.assertNull("Exception was caught.", exception);
}
/*
* For GF3233, Distinct process fail with NPE when relationship has NULL-valued target.
*/
public void testDistinctSelectForEmployeeWithNullAddress(){
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Employee emp = new Employee();
emp.setFirstName("Dummy");
emp.setLastName("Person");
em.persist(emp);
em.flush();
//"SELECT DISTINCT e.address FROM Employee e"
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Object> cq = qb.createQuery();
Root<Employee> rootEmp = cq.from(Employee.class);
cq.select(rootEmp.get("address"));
cq.distinct(true);
List<Object> resultList = em.createQuery(cq).getResultList();
}finally{
rollbackTransaction(em);
}
}
/*
* For 297385, Constructor expressions are not working with function arguments.
*/
public void testConstructorWithFunctionParameters(){
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Employee emp = new Employee();
emp.setFirstName("Very");
emp.setLastName("Dumb");
emp.setSalary(-100);//Employee pays to work?
em.persist(emp);
em.flush();
CriteriaBuilder qb = em.getCriteriaBuilder();
// Test constructor DataHolder(int)
CriteriaQuery<?> cq = qb.createQuery(DataHolder.class);
Root<Employee> from = cq.from(Employee.class);
EntityType<Employee> Emp_ = em.getMetamodel().entity(Employee.class);
cq.multiselect( qb.min(from.get(Emp_.getSingularAttribute("salary", int.class))));
List<?> resultList = em.createQuery(cq).getResultList();
Object resultObject = resultList.get(0);
assertTrue("constructor expression test expected DataHolder object, got " + resultObject,(resultObject instanceof DataHolder));
assertEquals("Expected DataHolder to contain int value of -100, Got :" + resultObject, -100, ((DataHolder)resultObject).getPrimitiveInt());
} finally {
rollbackTransaction(em);
}
}
public void testNonExistentConstructorCriteriaQuery(){
Exception expectedException = null;
EntityManager em = createEntityManager();
CriteriaBuilder qb = em.getCriteriaBuilder();
// Test constructor object:
CriteriaQuery<?> cq = qb.createQuery(DataHolder.class);
Root<Employee> from = cq.from(Employee.class);
EntityType<Employee> Emp_ = em.getMetamodel().entity(Employee.class);
//IllegalArgumentException expected from multiselect since DataHolder(String) does not exist
try{
cq.multiselect( from.get(Emp_.getSingularAttribute("lastName", String.class)));
Query query = em.createQuery(cq);
} catch (IllegalArgumentException exception){
expectedException = exception;
}
assertNotNull("Expected IllegalArgumentException not thrown when using a non-existing constructor", expectedException);
}
public void testIsNullAndIsNotNull(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
Employee emp = (Employee)em.createQuery("select e from Employee e where e.firstName = 'John' and e.lastName = 'Way'").getSingleResult();
emp.setFirstName(null);
emp = (Employee)em.createQuery("select e from Employee e where e.firstName = 'Charles' and e.lastName = 'Chanley'").getSingleResult();
emp.setFirstName(null);
emp.setLastName(null);
em.flush();
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<?> cq = qb.createQuery(Employee.class);
Root<Employee> from = cq.from(Employee.class);
EntityType<Employee> Emp_ = em.getMetamodel().entity(Employee.class);
List<Predicate> criteriaList = new ArrayList<Predicate>();
criteriaList.add(qb.isNotNull(from.get(Emp_.getSingularAttribute("lastName", String.class))));
criteriaList.add(qb.isNull(from.get(Emp_.getSingularAttribute("firstName", String.class))));
Predicate criteria = qb.and(criteriaList.toArray(new Predicate[0]));
cq.where(criteria);
Query query = em.createQuery(cq);
List results = query.getResultList();
assertTrue(results.size() == 1);
emp = (Employee)results.get(0);
assertTrue(emp.getFirstName() == null);
assertTrue(emp.getLastName() != null);
} finally {
rollbackTransaction(em);
}
}
public void testIsNullOrIsNull(){
EntityManager em = createEntityManager();
beginTransaction(em);
Employee emp = (Employee)em.createQuery("select e from Employee e where e.firstName = 'John' and e.lastName = 'Way'").getSingleResult();
emp.setFirstName(null);
emp = (Employee)em.createQuery("select e from Employee e where e.firstName = 'Charles' and e.lastName = 'Chanley'").getSingleResult();
emp.setLastName(null);
em.flush();
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<?> cq = qb.createQuery(Employee.class);
Root<Employee> from = cq.from(Employee.class);
EntityType<Employee> Emp_ = em.getMetamodel().entity(Employee.class);
List<Predicate> criteriaList = new ArrayList<Predicate>();
criteriaList.add(qb.isNull(from.get(Emp_.getSingularAttribute("lastName", String.class))));
criteriaList.add(qb.isNull(from.get(Emp_.getSingularAttribute("firstName", String.class))));
Predicate criteria = qb.or(criteriaList.toArray(new Predicate[0]));
cq.where(criteria);
Query query = em.createQuery(cq);
List results = query.getResultList();
assertTrue(results.size() == 2);
rollbackTransaction(em);
}
}