blob: 6d237cc92fa611e6610f004bf843fc7c25ca7112 [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 2018 IBM Corporation. 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:
// Oracle - initial API and implementation from Oracle TopLink
// 02/03/2017 - Dalia Abo Sheasha
// - 509693 : EclipseLink generates inconsistent SQL statements for SubQuery
package org.eclipse.persistence.testing.tests.jpa.criteria;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;
import java.math.BigInteger;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Vector;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Parameter;
import jakarta.persistence.Query;
import jakarta.persistence.Tuple;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaBuilder.In;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Fetch;
import jakarta.persistence.criteria.Join;
import jakarta.persistence.criteria.JoinType;
import jakarta.persistence.criteria.ParameterExpression;
import jakarta.persistence.criteria.Path;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Subquery;
import jakarta.persistence.metamodel.EmbeddableType;
import jakarta.persistence.metamodel.EntityType;
import jakarta.persistence.metamodel.Metamodel;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.persistence.config.CacheUsage;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.config.QueryType;
import org.eclipse.persistence.config.ResultSetConcurrency;
import org.eclipse.persistence.config.ResultSetType;
import org.eclipse.persistence.config.ResultType;
import org.eclipse.persistence.internal.jpa.querydef.CompoundExpressionImpl;
import org.eclipse.persistence.internal.jpa.querydef.CriteriaQueryImpl;
import org.eclipse.persistence.internal.jpa.querydef.FromImpl;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.JpaCriteriaBuilder;
import org.eclipse.persistence.jpa.JpaQuery;
import org.eclipse.persistence.queries.Cursor;
import org.eclipse.persistence.queries.ScrollableCursor;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.testing.framework.QuerySQLTracker;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
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.Dealer;
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator;
import org.eclipse.persistence.testing.models.jpa.advanced.EmploymentPeriod;
import org.eclipse.persistence.testing.models.jpa.advanced.PhoneNumber;
import org.eclipse.persistence.testing.models.jpa.advanced.Project;
import org.eclipse.persistence.testing.tests.jpa.jpql.JUnitDomainObjectComparer;
/**
* <p>
* <b>Purpose</b>: Test advanced JPA Query functionality.
* <p>
* <b>Description</b>: This tests query hints, caching and query optimization.
*
*/
public class AdvancedCriteriaQueryTestSuite extends JUnitTestCase {
static JUnitDomainObjectComparer comparer; //the global comparer object used in all tests
public AdvancedCriteriaQueryTestSuite() {
super();
}
public AdvancedCriteriaQueryTestSuite(String name) {
super(name);
}
// This method is run at the start of EVERY test case method.
@Override
public void setUp() {
}
// 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("AdvancedCriteriaQueryTestSuite");
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSetup"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testInCollectionEntity"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testInCollectionPrimitives"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testInParameterCollection"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testInParameterCollection2"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testProd"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSize"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testJoinDistinct"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSome"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereConjunction"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereNotConjunction"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereDisjunction"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereNotDisjunction"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereConjunctionAndDisjunction"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereDisjunctionAndConjunction"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereConjunctionOrDisjunction"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereUsingAndWithPredicates"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testWhereUsingOrWithPredicates"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testVerySimpleJoin"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testGroupByHaving"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testGroupByHaving2"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testAlternateSelection"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryExists"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryNotExists"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryExistsAfterAnd"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryExistsBeforeAnd"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryNotExistsAfterAnd"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryNotExistsBeforeAnd"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryExistsNested"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryExistsNestedUnusedRoot"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryExistsNestedAfterAnd"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubqueryExistsNestedAfterLiteralAnd"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSubQuery"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testInSubQuery"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testInLiteral"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testInlineInParameter"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSimpleJoin"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSimpleFetch"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testObjectResultType"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSimple"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSimpleWhere"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSimpleWhereObject"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testSharedWhere"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testTupleQuery"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testQueryCacheFirstCacheHits"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testQueryCacheOnlyCacheHits"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testQueryCacheOnlyCacheHitsOnSession"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testQueryExactPrimaryKeyCacheHits"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testQueryHintFetch"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testCursors"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testIsEmpty"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testNeg"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testIsMember"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testIsMemberEntity"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testNullRestrictionGetRestriction"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testFromToExpression"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testUnusedJoinDoesNotAffectOtherJoins"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testUnusedJoinDoesNotAffectFetchJoin"));
// Bug 464833
suite.addTest(new AdvancedCriteriaQueryTestSuite("testGetRestrictionReturningCorrectPredicate"));
suite.addTest(new AdvancedCriteriaQueryTestSuite("testJoinDuplication"));
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();
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 void testAlternateSelection() {
EntityManager em = createEntityManager();
beginTransaction(em);
try {
em.createQuery("select p.teamLeader from Project p where p.name = 'Sales Reporting'").getResultList();
Metamodel mm = em.getMetamodel();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Project> spouse = cquery.from(Project.class);
cquery.where(qbuilder.equal(spouse.get("name"), "Sales Reporting")).select(spouse.<Employee> get("teamLeader"));
TypedQuery<Employee> tquery = em.createQuery(cquery);
assertTrue("Did not find the correct leaders of Project Swirly Dirly.", tquery.getResultList().size() > 1);
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Test that a cache hit will occur on a primary key query.
*/
public void testTupleQuery() {
EntityManager em = createEntityManager();
QuerySQLTracker counter = null;
beginTransaction(em);
try {
// Load an employee into the cache.
CriteriaBuilder qb = em.getCriteriaBuilder();
Query query = em.createQuery(em.getCriteriaBuilder().createQuery(Employee.class));
List result = query.getResultList();
Employee employee = (Employee)result.get(0);
// Count SQL.
counter = new QuerySQLTracker(getServerSession());
// Query by primary key.
CriteriaQuery<Tuple> cq = qb.createQuery(Tuple.class);
Root from = cq.from(Employee.class);
cq.multiselect(from.get("id"), from.get("firstName"));
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")), qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName"))));
TypedQuery<Tuple> typedQuery = em.createQuery(cq);
typedQuery.setParameter("id", employee.getId());
typedQuery.setParameter("firstName", employee.getFirstName());
Tuple queryResult = typedQuery.getSingleResult();
assertTrue("Query Results do not match selection", queryResult.get(0).equals(employee.getId()) && queryResult.get(1).equals(employee.getFirstName()));
} finally {
rollbackTransaction(em);
if (counter != null) {
counter.remove();
}
}
}
public void testSharedWhere() {
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
cq.where(qb.equal(root.get("firstName"), qb.literal("Bob")));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
assertTrue("Did not return Employee", result.get(0).getClass().equals(Employee.class));
assertTrue("Employee had wrong firstname", result.get(0).getFirstName().equalsIgnoreCase("bob"));
CriteriaQuery<Employee> cq2 = em.getCriteriaBuilder().createQuery(Employee.class);
cq2.where(cq.getRestriction());
TypedQuery<Employee> tq2 = em.createQuery(cq);
List<Employee> result2 = tq.getResultList();
assertTrue("Employee's did not match with query with same where clause", comparer.compareObjects(result.get(0), result2.get(0)));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSimple(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
List<Employee> result = em.createQuery(cq).getResultList();
assertFalse("No Employees were returned", result.isEmpty());
assertTrue("Did not return Employee", result.get(0).getClass().equals(Employee.class));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testGroupByHaving(){
EntityManager em = createEntityManager();
List<Object> jpqlResult = em.createQuery("Select e.address, count(e) from Employee e group by e.address having count(e.address) < 3").getResultList();
beginTransaction(em);
try {
Metamodel mm = em.getMetamodel();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Object> cquery = qbuilder.createQuery();
Root<Employee> customer = cquery.from(Employee.class);
cquery.multiselect(customer.get("address"), qbuilder.count(customer));
cquery.groupBy(customer.get("address"));
cquery.having(qbuilder.lt(qbuilder.count(customer.get("address")), 3));
List<Object> result = em.createQuery(cquery).getResultList();
assertTrue(comparer.compareObjects(jpqlResult, result));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testGroupByHaving2(){
EntityManager em = createEntityManager();
List<Object> jpqlResult = em.createQuery("Select e.period, count(e) from Employee e group by e.period having count(e.period) > 3").getResultList();
beginTransaction(em);
try {
Metamodel mm = em.getMetamodel();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Object> cquery = qbuilder.createQuery();
Root<Employee> customer = cquery.from(Employee.class);
EntityType<Employee> Customer_ = customer.getModel();
EmbeddableType<EmploymentPeriod> Country_ = mm.embeddable(EmploymentPeriod.class);
cquery.multiselect(customer.get(Customer_.getSingularAttribute("period", EmploymentPeriod.class)), qbuilder.count(customer));
cquery.groupBy(customer.get(Customer_.getSingularAttribute("period", EmploymentPeriod.class)));
cquery.having(qbuilder.gt(qbuilder.count(customer.get(Customer_.getSingularAttribute("period", EmploymentPeriod.class))), 3));
List<Object> result = em.createQuery(cquery).getResultList();
assertTrue(comparer.compareObjects(jpqlResult, result));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testInLiteral(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
In<String> in = qb.in(emp.get("address").<String>get("city"));
in.value("Ottawa").value("Halifax").value("Toronto");
cq.where(in);
List<Employee> result = em.createQuery(cq).getResultList();
assertFalse("No Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testInSubQuery(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
Subquery<String> sq = cq.subquery(String.class);
Root<Address> sqEmp = sq.from(Address.class);
sq.select(sqEmp.<String>get("city"));
sq.where(qb.notLike(sqEmp.<String>get("city"), "5"));
In<String> in = qb.in(emp.get("address").<String>get("city"));
in.value(sq);
cq.where(in);
List<Employee> result = em.createQuery(cq).getResultList();
assertFalse("No Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testInCollectionEntity(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
Root<PhoneNumber> phone = cq.from(PhoneNumber.class);
cq.where(qb.and(qb.equal(phone.get("areaCode"), "613"), phone.in(emp.<Collection<?>>get("phoneNumbers"))));
Query query = em.createQuery(cq);
List<Employee> result = query.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testInCollectionPrimitives(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
Root<PhoneNumber> phone = cq.from(PhoneNumber.class);
cq.where(qb.literal("Bug fixes").in(emp.<Collection<?>>get("responsibilities")));
Query query = em.createQuery(cq);
List<Employee> result = query.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testInCollectionEmpty(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
Root<PhoneNumber> phone = cq.from(PhoneNumber.class);
cq.where(qb.literal("Bug fixes").in(new HashSet()));
Query query = em.createQuery(cq);
List<Employee> result = query.getResultList();
assertTrue("No any Employees was expected", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testInCollectionNull(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
Root<PhoneNumber> phone = cq.from(PhoneNumber.class);
List list = null;
cq.where(qb.literal("Bug fixes").in(list));
Query query = em.createQuery(cq);
List<Employee> result = query.getResultList();
assertTrue("No any Employees was expected", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/*
* bug 349477 - Using criteria.in(...) with ParameterExpression of type Collection creates invalid SQL
*/
public void testInParameterCollection(){
EntityManager em = createEntityManager();
beginTransaction(em);
List respons = new Vector();
respons.add("NoResults");
respons.add("Bug fixes");
try {
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery =qbuilder.createQuery(Employee.class);
Root<Employee> emp = cquery.from(Employee.class);
ParameterExpression pe = qbuilder.parameter(java.util.Collection.class, "param");
cquery.where(emp.join("responsibilities").in(pe));
List<Employee> result = em.createQuery(cquery).setParameter("param",respons).getResultList();
assertFalse("testInParameterCollection failed: No Employees were returned", result.isEmpty());
} finally {
closeEntityManagerAndTransaction(em);
}
}
/*
* bug 349477 - Using criteria.in(...) with ParameterExpression of type Collection creates invalid SQL
*/
public void testInParameterCollection2(){
EntityManager em = createEntityManager();
beginTransaction(em);
List<String> response = new Vector<>();
response.add("NoResults");
response.add("Bug fixes");
try {
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> emp = cquery.from(Employee.class);
cquery.where(emp.join("responsibilities").in(qbuilder.parameter(java.util.Collection.class, "param")));
List<Employee> result = em.createQuery(cquery).setParameter("param", response).getResultList();
assertFalse("testInParameterCollection failed: No Employees were returned", result.isEmpty());
} finally {
closeEntityManagerAndTransaction(em);
}
}
public void testInlineInParameter(){
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
cq.where(emp.get("address").<String>get("city").in(qb.parameter(String.class, "city")));
Query query = em.createQuery(cq);
query.setParameter("city", "Ottawa");
List<Employee> result = query.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testIsEmpty(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
cq.where(qb.isEmpty(emp.<Collection<PhoneNumber>>get("phoneNumbers")));
List<Employee> result = em.createQuery(cq).getResultList();
assertFalse("No Employees were returned", result.isEmpty());
for (Employee e : result){
assertTrue("PhoneNumbers Found", e.getPhoneNumbers().isEmpty());
}
}finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testNeg(){
if (getPlatform().isSymfoware()) {
getServerSession().logMessage("Test testNeg skipped for this platform, "
+ "Symfoware doesn't allow arithmetic expression in subquery. (bug 304907)");
return;
}
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
cq.where(qb.lessThan(qb.neg(qb.size(emp.<Collection<PhoneNumber>>get("phoneNumbers"))), 0));
List<Employee> result = em.createQuery(cq).getResultList();
assertFalse("No Employees were returned", result.isEmpty());
for (Employee e : result){
assertTrue("PhoneNumbers Found", ! e.getPhoneNumbers().isEmpty());
}
}finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testNullIf(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
cq.where(qb.isNull(qb.nullif(qb.size(emp.<Collection<PhoneNumber>>get("phoneNumbers")), qb.parameter(Integer.class))));
List<Employee> result = em.createQuery(cq).getResultList();
assertFalse("No Employees were returned", result.isEmpty());
for (Employee e : result){
assertTrue("PhoneNumbers Found", ! e.getPhoneNumbers().isEmpty());
}
}finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testNullRestrictionGetRestriction() {
EntityManager em = createEntityManager();
beginTransaction(em);
try {
Metamodel mm = em.getMetamodel();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
cquery.getRestriction();
}catch (NullPointerException ex){
fail("'getRestriction()' with null restriction threw NullPointerException");
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testIsMember(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
cq.where(qb.isMember(qb.parameter(String.class,"1"), emp.<Collection<String>>get("responsibilities")));
Query query = em.createQuery(cq);
query.setParameter("1", "Sort files");
List<Employee> result = query.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
for (Employee e : result){
assertTrue("Employee Found without Responcibilities", e.getResponsibilities().contains("Sort files"));
}
}finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testIsMemberEntity(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee> cq = qb.createQuery(Employee.class);
Root<Employee> emp = cq.from(Employee.class);
Root<PhoneNumber> phone = cq.from(PhoneNumber.class);
cq.where(qb.and(qb.equal(phone.get("areaCode"), "416"), qb.isMember(phone, emp.<Collection<PhoneNumber>>get("phoneNumbers"))));
Query query = em.createQuery(cq);
List<Employee> result = query.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
for (Employee e : result){
boolean areacode = false;
for (PhoneNumber p : e.getPhoneNumbers()){
areacode = areacode || p.getAreaCode().equals("416");
}
assertTrue("No PhoneNumbers with '416'area code", areacode);
}
}finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testVerySimpleJoin(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
root.join("phoneNumbers");
if (usesSOP() && getServerSession().getPlatform().isOracle()) {
// distinct is incompatible with blob in selection clause on Oracle
} else {
cq.distinct(true);
}
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
for (Employee emp : result){
assertFalse("Found someone without a phone", emp.getPhoneNumbers().isEmpty());
}
}finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSimpleJoin(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
root.join("phoneNumbers");
cq.where(qb.isEmpty(root.<Collection<PhoneNumber>>get("phoneNumbers")));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertTrue("Found employee but joins should have canceled isEmpty", result.isEmpty());
}finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSimpleWhere(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
cq.where(qb.equal(root.get("firstName"), qb.literal("Bob")));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
assertTrue("Did not return Employee", result.get(0).getClass().equals(Employee.class));
assertTrue("Employee had wrong firstname", result.get(0).getFirstName().equalsIgnoreCase("bob"));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testWhereDisjunction(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
cq.where(qb.disjunction());
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertTrue("Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
//Added for bug 413084
public void testWhereNotDisjunction(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
cq.where(qb.disjunction().not());
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertFalse("Employees were not returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testWhereConjunction(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
cq.where(qb.conjunction());
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertFalse("Employees were not returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testWhereNotConjunction(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
cq.where(qb.conjunction().not());
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertTrue("Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testJoinDistinct(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
Fetch<Employee, Project> o = customer.fetch("phoneNumbers", JoinType.LEFT);
cquery.where(customer.get("address").get("city").in("Ottawa", "Halifax"));
cquery.select(customer).distinct(true);
TypedQuery<Employee> tquery = em.createQuery(cquery);
if (usesSOP() && getServerSession().getPlatform().isOracle()) {
// distinct is incompatible with blob in selection clause on Oracle
tquery.setHint(QueryHints.SERIALIZED_OBJECT, "false");
}
List<Employee> result = tquery.getResultList();
assertFalse ("No results found", result.isEmpty());
Long count = (Long)em.createQuery("Select count(e) from Employee e where e.address.city in ('Ottawa', 'Halifax')").getSingleResult();
assertTrue("Incorrect number of results returned", result.size() == count);
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testWhereConjunctionAndDisjunction(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
cq.where(qb.and(qb.disjunction(), qb.conjunction()));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertTrue("Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testWhereDisjunctionAndConjunction(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
cq.where(qb.and(qb.conjunction(), qb.disjunction()));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertTrue("Employees were returned", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testWhereConjunctionOrDisjunction(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
cq.where(qb.or(qb.disjunction(), qb.conjunction()));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertTrue("Employees were not returned", !result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testWhereUsingAndWithPredicates(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
cq.where(qb.and(qb.conjunction(), qb.equal(root.get("lastName"), "Smith")));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertFalse("Employees were not returned for 'true and lastName='Smith' '", result.isEmpty());
cq = em.getCriteriaBuilder().createQuery(Employee.class);
qb = em.getCriteriaBuilder();
root = cq.from(em.getMetamodel().entity(Employee.class));
cq.where(qb.and(qb.equal(root.get("lastName"), "Smith"), qb.conjunction()));
tq = em.createQuery(cq);
result = tq.getResultList();
assertFalse("Employees were not returned for 'lastName='Smith' and true'", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testWhereUsingOrWithPredicates(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
cq.where(qb.or(qb.disjunction(), qb.equal(root.get("lastName"), "Smith")));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertFalse("Employees were not returned for 'false or lastName='Smith' '", result.isEmpty());
cq = em.getCriteriaBuilder().createQuery(Employee.class);
qb = em.getCriteriaBuilder();
root = cq.from(em.getMetamodel().entity(Employee.class));
cq.where(qb.or(qb.equal(root.get("lastName"), "Smith"), qb.disjunction()));
tq = em.createQuery(cq);
result = tq.getResultList();
assertFalse("Employees were not returned for 'lastName='Smith' or false'", result.isEmpty());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSimpleWhereObject(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery cq = em.getCriteriaBuilder().createQuery();
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
cq.where(qb.equal(root.get("firstName"), qb.literal("Bob")));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
assertTrue("Did not return Employee", result.get(0).getClass().equals(Employee.class));
assertTrue("Employee had wrong firstname", result.get(0).getFirstName().equalsIgnoreCase("bob"));
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSimpleFetch(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
root.fetch("projects");
cq.where(qb.equal(root.get("firstName"), qb.literal("Bob")));
TypedQuery<Employee> tq = em.createQuery(cq);
List<Employee> result = tq.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
ObjectOutputStream stream = new ObjectOutputStream(byteStream);
stream.writeObject(result.get(0));
stream.flush();
byte arr[] = byteStream.toByteArray();
ByteArrayInputStream inByteStream = new ByteArrayInputStream(arr);
ObjectInputStream inObjStream = new ObjectInputStream(inByteStream);
Employee emp = (Employee) inObjStream.readObject();
assertTrue("Did not return Employee", emp.getClass().equals(Employee.class));
assertTrue("Employee had wrong firstname", emp.getFirstName().equalsIgnoreCase("bob"));
emp.getProjects().size(); //may cause exception
} catch (IOException e) {
fail("Failed during serialization");
} catch (ClassNotFoundException e) {
fail("Failed during serialization");
}
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSize(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
// em.createQuery("Select size(e.responsibilities) from Employee e").getResultList();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Object[]> cquery = qbuilder.createQuery(Object[].class);
Root<Employee> customer = cquery.from(Employee.class);
cquery.select(qbuilder.array(customer.get("id"), qbuilder.size(customer.<Collection<String>>get("responsibilities"))));
TypedQuery<Object[]> tquery = em.createQuery(cquery);
List<Object[]> result = tquery.getResultList();
for(Object[] value : result){
assertTrue("Incorrect responsibilities count", em.find(Employee.class, value[0]).getResponsibilities().size() == (Integer) value[1]);
}
// No assert as version is not actually a mapped field in dealer.
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSome(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
em.createQuery("SELECT e from Employee e, IN(e.phoneNumbers) p where p.type = some(select p2.type from PhoneNumber p2 where p2.areaCode = '613')").getResultList();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
// Get Root Customer
Root<Employee> customer = cquery.from(Employee.class);
// Join Customer-Order
Join<Employee, PhoneNumber> orders= customer.join("phoneNumbers");
// create Subquery instance
Subquery<String> sq = cquery.subquery(String.class);
// Create Roots
Root<PhoneNumber> order = sq.from(PhoneNumber.class);
// Create SubQuery
sq.select(order.<String>get("type")).
where(qbuilder.equal(order.get("areaCode"), "613"));
// Create Main Query with SubQuery
cquery.where(qbuilder.equal(orders.<String>get("type"), qbuilder.some(sq)));
if (usesSOP() && getServerSession().getPlatform().isOracle()) {
// distinct is incompatible with blob in selection clause on Oracle
} else {
cquery.distinct(true);
}
em.createQuery(cquery).getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testSubQuery(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
Join<Employee, Dealer> o = customer.join("dealers");
if (usesSOP() && getServerSession().getPlatform().isOracle()) {
// distinct is incompatible with blob in selection clause on Oracle
cquery.select(customer);
} else {
cquery.select(customer).distinct(true);
}
Subquery<Integer> sq = cquery.subquery(Integer.class);
Root<Dealer> sqo = sq.from(Dealer.class);
sq.select(qbuilder.min(sqo.<Integer>get("version")));
cquery.where(qbuilder.equal(o.get("version"), sq));
TypedQuery<Employee> tquery = em.createQuery(cquery);
List<Employee> result = tquery.getResultList();
// No assert as version is not actually a mapped field in dealer.
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testFromToExpression() {
EntityManager em = createEntityManager();
beginTransaction(em);
try{
JpaCriteriaBuilder cb = (JpaCriteriaBuilder)em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = cb.createQuery(Employee.class);
Root<Employee> emp = cquery.from(Employee.class);
cquery.where(cb.fromExpression(cb.toExpression(emp).get("id").notNull()));
TypedQuery<Employee> tquery = em.createQuery(cquery);
List<Employee> result = tquery.getResultList();
result.size();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
protected static Set<Integer> getIds(Collection<Employee> employees) {
Set<Integer> ids = new HashSet<Integer>(employees.size());
for (Employee emp : employees) {
ids.add(emp.getId());
}
return ids;
}
protected void compareIds(List<Employee> jpqlEmployees, List<Employee> criteriaEmployees) {
Set<Integer> jpqlIds = getIds(jpqlEmployees);
Set<Integer> criteriaIds = getIds(criteriaEmployees);
if (!jpqlIds.equals(criteriaIds)) {
fail("jpql: " + jpqlIds + "; criteria: " + criteriaIds);
}
}
public void testSubqueryExists() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e WHERE EXISTS (SELECT p FROM e.projects p)").getResultList();
em.clear();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
// create correlated subquery
Subquery<Project> sq = cquery.subquery(Project.class);
Root<Employee> sqc = sq.correlate(customer);
Path<Project> sqo = sqc.join("projects");
sq.select(sqo);
cquery.where(qbuilder.exists(sq));
TypedQuery<Employee> tquery = em.createQuery(cquery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone without projects", !emp.getProjects().isEmpty());
}
}
public void testSubqueryNotExists() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e WHERE NOT EXISTS (SELECT p FROM e.projects p)").getResultList();
em.clear();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
// create correlated subquery
Subquery<Project> sq = cquery.subquery(Project.class);
Root<Employee> sqc = sq.correlate(customer);
Path<Project> sqo = sqc.join("projects");
sq.select(sqo);
cquery.where(qbuilder.not(qbuilder.exists(sq)));
TypedQuery<Employee> tquery = em.createQuery(cquery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone with projects", emp.getProjects().isEmpty());
}
}
// cquery.where(qbuilder.and(isMale, qbuilder.exists(sq)));
public void testSubqueryExistsAfterAnd() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e WHERE e.gender = org.eclipse.persistence.testing.models.jpa.advanced.Employee.Gender.Male AND EXISTS (SELECT p FROM e.projects p)").getResultList();
em.clear();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
// create correlated subquery
Subquery<Project> sq = cquery.subquery(Project.class);
Root<Employee> sqc = sq.correlate(customer);
Path<Project> sqo = sqc.join("projects");
sq.select(sqo);
Predicate isMale = qbuilder.equal(customer.get("gender"), Employee.Gender.Male);
cquery.where(qbuilder.and(isMale, qbuilder.exists(sq)));
TypedQuery<Employee> tquery = em.createQuery(cquery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone not male", emp.getGender() != null && emp.isMale());
assertTrue("Found someone without projects", !emp.getProjects().isEmpty());
}
}
// cquery.where(qbuilder.and(qbuilder.exists(sq), isMale));
public void testSubqueryExistsBeforeAnd() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e WHERE EXISTS (SELECT p FROM e.projects p) AND e.gender = org.eclipse.persistence.testing.models.jpa.advanced.Employee.Gender.Male").getResultList();
em.clear();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
// create correlated subquery
Subquery<Project> sq = cquery.subquery(Project.class);
Root<Employee> sqc = sq.correlate(customer);
Path<Project> sqo = sqc.join("projects");
sq.select(sqo);
Predicate isMale = qbuilder.equal(customer.get("gender"), Employee.Gender.Male);
cquery.where(qbuilder.and(qbuilder.exists(sq), isMale));
TypedQuery<Employee> tquery = em.createQuery(cquery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone not male", emp.getGender() != null && emp.isMale());
assertTrue("Found someone without projects", !emp.getProjects().isEmpty());
}
}
// cquery.where(qbuilder.and(isFemale, qbuilder.not(qbuilder.exists(sq))));
public void testSubqueryNotExistsAfterAnd() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e WHERE e.gender = org.eclipse.persistence.testing.models.jpa.advanced.Employee.Gender.Female AND NOT EXISTS (SELECT p FROM e.projects p)").getResultList();
em.clear();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
// create correlated subquery
Subquery<Project> sq = cquery.subquery(Project.class);
Root<Employee> sqc = sq.correlate(customer);
Path<Project> sqo = sqc.join("projects");
sq.select(sqo);
Predicate isFemale = qbuilder.equal(customer.get("gender"), Employee.Gender.Female);
cquery.where(qbuilder.and(isFemale, qbuilder.not(qbuilder.exists(sq))));
TypedQuery<Employee> tquery = em.createQuery(cquery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone not female", emp.getGender() != null && emp.isFemale());
assertTrue("Found someone with projects", emp.getProjects().isEmpty());
}
}
// cquery.where(qbuilder.and(qbuilder.not(qbuilder.exists(sq)), isFemale));
public void testSubqueryNotExistsBeforeAnd() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e WHERE NOT EXISTS (SELECT p FROM e.projects p) AND e.gender = org.eclipse.persistence.testing.models.jpa.advanced.Employee.Gender.Female").getResultList();
em.clear();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
// create correlated subquery
Subquery<Project> sq = cquery.subquery(Project.class);
Root<Employee> sqc = sq.correlate(customer);
Path<Project> sqo = sqc.join("projects");
sq.select(sqo);
Predicate isFemale = qbuilder.equal(customer.get("gender"), Employee.Gender.Female);
cquery.where(qbuilder.and(qbuilder.not(qbuilder.exists(sq)), isFemale));
TypedQuery<Employee> tquery = em.createQuery(cquery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone not female", emp.getGender() != null && emp.isFemale());
assertTrue("Found someone with projects", emp.getProjects().isEmpty());
}
}
public void testSubqueryExistsNested() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e join e.projects ep WHERE EXISTS (SELECT p FROM Project p WHERE ep = p AND EXISTS (SELECT t FROM Employee t WHERE p.teamLeader = t))").getResultList();
em.clear();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Employee> mainQuery = builder.createQuery(Employee.class);
Subquery<Object> subQuery1 = mainQuery.subquery(Object.class);
Subquery<Object> subQuery2 = subQuery1.subquery(Object.class);
Root<Employee> mainEmployee = mainQuery.from(Employee.class);
mainQuery.select(mainEmployee);
Root<Project> sub1Project = subQuery1.from(Project.class);
Join<Employee, Project> mainEmployeeProjects = mainEmployee.join("projects");
Root<Employee> sub2Employee = subQuery2.from(Employee.class);
Join<Employee, Employee> sub1ProjectTeamLeader = sub1Project.join("teamLeader");
subQuery2.where(builder.equal(sub2Employee, sub1ProjectTeamLeader));
subQuery1.where(builder.and(builder.exists(subQuery2), builder.equal(sub1Project, mainEmployeeProjects)));
mainQuery.where(builder.exists(subQuery1));
TypedQuery<Employee> tquery = em.createQuery(mainQuery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone without projects", !emp.getProjects().isEmpty());
boolean atLeastOneProjectHasLeader = false;
for (Project proj : emp.getProjects()) {
if (proj.getTeamLeader() != null) {
atLeastOneProjectHasLeader = true;
break;
}
}
assertTrue("None of employee's projects has a leader", atLeastOneProjectHasLeader);
}
}
public void testSubqueryExistsNestedUnusedRoot() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e join e.projects ep WHERE EXISTS (SELECT p FROM Project p WHERE ep = p AND EXISTS (SELECT t FROM Employee t WHERE p.teamLeader = t))").getResultList();
em.clear();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Employee> mainQuery = builder.createQuery(Employee.class);
Subquery<Object> subQuery1 = mainQuery.subquery(Object.class);
Subquery<Object> subQuery2 = subQuery1.subquery(Object.class);
// Add an unused Root
mainQuery.from(Dealer.class);
Root<Employee> mainEmployee = mainQuery.from(Employee.class);
// Add another unused Root
mainQuery.from(Address.class);
mainQuery.select(mainEmployee);
Root<Project> sub1Project = subQuery1.from(Project.class);
Join<Employee, Project> mainEmployeeProjects = mainEmployee.join("projects");
Root<Employee> sub2Employee = subQuery2.from(Employee.class);
Join<Employee, Employee> sub1ProjectTeamLeader = sub1Project.join("teamLeader");
subQuery2.where(builder.equal(sub2Employee, sub1ProjectTeamLeader));
subQuery1.where(builder.and(builder.exists(subQuery2), builder.equal(sub1Project, mainEmployeeProjects)));
mainQuery.where(builder.exists(subQuery1));
TypedQuery<Employee> tquery = em.createQuery(mainQuery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone without projects", !emp.getProjects().isEmpty());
boolean atLeastOneProjectHasLeader = false;
for (Project proj : emp.getProjects()) {
if (proj.getTeamLeader() != null) {
atLeastOneProjectHasLeader = true;
break;
}
}
assertTrue("None of employee's projects has a leader", atLeastOneProjectHasLeader);
}
}
public void testSubqueryExistsNestedAfterAnd() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e join e.projects ep WHERE e.gender = org.eclipse.persistence.testing.models.jpa.advanced.Employee.Gender.Male AND EXISTS (SELECT p FROM Project p WHERE 'Sales Reporting' <> p.name AND ep = p AND EXISTS (SELECT t FROM Employee t WHERE p.teamLeader = t))").getResultList();
em.clear();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Employee> mainQuery = builder.createQuery(Employee.class);
Subquery<Object> subQuery1 = mainQuery.subquery(Object.class);
Subquery<Object> subQuery2 = subQuery1.subquery(Object.class);
Root<Employee> mainEmployee = mainQuery.from(Employee.class);
mainQuery.select(mainEmployee);
Root<Project> sub1Project = subQuery1.from(Project.class);
Join<Employee, Project> mainEmployeeProjects = mainEmployee.join("projects");
Root<Employee> sub2Employee = subQuery2.from(Employee.class);
Join<Employee, Employee> sub1ProjectTeamLeader = sub1Project.join("teamLeader");
subQuery2.where(builder.equal(sub2Employee, sub1ProjectTeamLeader));
Predicate notSalesReporting = builder.not(builder.equal(builder.literal("Sales Reporting"), sub1Project.get("name")));
subQuery1.where(builder.and(notSalesReporting, builder.and(builder.exists(subQuery2), builder.equal(sub1Project, mainEmployeeProjects))));
Predicate isMale = builder.equal(mainEmployee.get("gender"), Employee.Gender.Male);
mainQuery.where(builder.and(isMale, builder.exists(subQuery1)));
TypedQuery<Employee> tquery = em.createQuery(mainQuery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone not male", emp.getGender() != null && emp.isMale());
assertTrue("Found someone without projects", !emp.getProjects().isEmpty());
boolean atLeastOneProjectHasLeader = false;
for (Project proj : emp.getProjects()) {
if (!proj.getName().equals("Sales Reporting")) {
if (proj.getTeamLeader() != null) {
atLeastOneProjectHasLeader = true;
break;
}
}
}
assertTrue("None of employee's projects has a leader", atLeastOneProjectHasLeader);
}
}
public void testSubqueryExistsNestedAfterLiteralAnd() {
EntityManager em = createEntityManager();
List<Employee> jpqlEmployees;
List<Employee> criteriaEmployees;
beginTransaction(em);
try {
jpqlEmployees = em.createQuery("SELECT e FROM Employee e join e.projects ep WHERE EXISTS (SELECT p FROM Project p WHERE ep = p AND EXISTS (SELECT t FROM Employee t WHERE p.teamLeader = t))").getResultList();
em.clear();
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Employee> mainQuery = builder.createQuery(Employee.class);
Subquery<Object> subQuery1 = mainQuery.subquery(Object.class);
Subquery<Object> subQuery2 = subQuery1.subquery(Object.class);
Root<Employee> mainEmployee = mainQuery.from(Employee.class);
mainQuery.select(mainEmployee);
Root<Project> sub1Project = subQuery1.from(Project.class);
Join<Employee, Project> mainEmployeeProjects = mainEmployee.join("projects");
Root<Employee> sub2Employee = subQuery2.from(Employee.class);
Join<Employee, Employee> sub1ProjectTeamLeader = sub1Project.join("teamLeader");
subQuery2.where(builder.equal(sub2Employee, sub1ProjectTeamLeader));
Predicate oneEqualsOne = builder.equal(builder.literal(1), builder.literal(1));
subQuery1.where(builder.and(oneEqualsOne, builder.and(builder.exists(subQuery2), builder.equal(sub1Project, mainEmployeeProjects))));
Predicate twoEqualsTwo = builder.equal(builder.literal(2), builder.literal(2));
mainQuery.where(builder.and(twoEqualsTwo, builder.exists(subQuery1)));
TypedQuery<Employee> tquery = em.createQuery(mainQuery);
criteriaEmployees = tquery.getResultList();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
compareIds(jpqlEmployees, criteriaEmployees);
for (Employee emp : criteriaEmployees){
assertTrue("Found someone without projects", !emp.getProjects().isEmpty());
boolean atLeastOneProjectHasLeader = false;
for (Project proj : emp.getProjects()) {
if (proj.getTeamLeader() != null) {
atLeastOneProjectHasLeader = true;
break;
}
}
assertTrue("None of employee's projects has a leader", atLeastOneProjectHasLeader);
}
}
/**
* Test cursored queries.
*/
public void testCursors() {
EntityManager em = createEntityManager();
beginTransaction(em);
try {
// Test cursored stream.
Query query = em.createQuery(em.getCriteriaBuilder().createQuery(Employee.class));
query.setHint(QueryHints.CURSOR, true);
query.setHint(QueryHints.CURSOR_INITIAL_SIZE, 2);
query.setHint(QueryHints.CURSOR_PAGE_SIZE, 5);
query.setHint(QueryHints.CURSOR_SIZE, "Select count(*) from CMP3_EMPLOYEE");
Cursor cursor = (Cursor)query.getSingleResult();
cursor.nextElement();
cursor.size();
cursor.close();
// Test cursor result API.
JpaQuery jpaQuery = (JpaQuery)((EntityManager)em.getDelegate()).createQuery(em.getCriteriaBuilder().createQuery(Employee.class));
jpaQuery.setHint(QueryHints.CURSOR, true);
cursor = jpaQuery.getResultCursor();
cursor.nextElement();
cursor.size();
cursor.close();
// Test scrollable cursor.
jpaQuery = (JpaQuery)((EntityManager)em.getDelegate()).createQuery(em.getCriteriaBuilder().createQuery(Employee.class));
jpaQuery.setHint(QueryHints.SCROLLABLE_CURSOR, true);
jpaQuery.setHint(QueryHints.RESULT_SET_CONCURRENCY, ResultSetConcurrency.ReadOnly);
String resultSetType = ResultSetType.DEFAULT;
// HANA supports only TYPE_FORWARD_ONLY, see bug 384116
if (getPlatform().isHANA()) {
resultSetType = ResultSetType.ForwardOnly;
}
jpaQuery.setHint(QueryHints.RESULT_SET_TYPE, resultSetType);
ScrollableCursor scrollableCursor = (ScrollableCursor)jpaQuery.getResultCursor();
scrollableCursor.next();
scrollableCursor.close();
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Test the result type of various queries.
*/
public void testObjectResultType() {
EntityManager em = createEntityManager();
beginTransaction(em);
try {
// Load an employee into the cache.
Query query = em.createQuery(em.getCriteriaBuilder().createQuery(Employee.class));
List result = query.getResultList();
Employee employee = (Employee)result.get(0);
CriteriaBuilder qb = em.getCriteriaBuilder();
// Test multi object, as an array.
CriteriaQuery<?> cq = qb.createQuery(Object[].class);
Root<Employee> from = cq.from(Employee.class);
cq.multiselect(from, from.get("address"), from.get("id"));
Parameter<String> firstNameParam = qb.parameter(from.<String>get("firstName").getModel().getBindableJavaType(), "firstName");
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")),qb.equal(from.get("firstName"), firstNameParam)));
query = em.createQuery(cq);
query.setParameter("id", employee.getId());
query.setParameter(firstNameParam, employee.getFirstName());
Object[] arrayResult = (Object[])query.getSingleResult();
if ((arrayResult.length != 3) && (arrayResult[0] != employee) || (arrayResult[1] != employee.getAddress()) || (!arrayResult[2].equals(employee.getId()))) {
fail("Array result not correct: " + arrayResult);
}
List listResult = query.getResultList();
arrayResult = (Object[])listResult.get(0);
if ((arrayResult.length != 3) || (arrayResult[0] != employee) || (arrayResult[1] != employee.getAddress()) || (!arrayResult[2].equals(employee.getId()))) {
fail("Array result not correct: " + arrayResult);
}
// Test single object, as an array.
cq = qb.createQuery(Object[].class);
from = cq.from(Employee.class);
cq.multiselect(from.get("id"));
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")), (qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName")))));
query = em.createQuery(cq);
query.setHint(QueryHints.RESULT_TYPE, ResultType.Array);
query.setParameter("id", employee.getId());
query.setParameter("firstName", employee.getFirstName());
arrayResult = (Object[])query.getSingleResult();
if ((arrayResult.length != 1) || (!arrayResult[0].equals(employee.getId()))) {
fail("Array result not correct: " + arrayResult);
}
listResult = query.getResultList();
arrayResult = (Object[])listResult.get(0);
if ((arrayResult.length != 1) || (!arrayResult[0].equals(employee.getId()))) {
fail("Array result not correct: " + arrayResult);
}
// Test multi object, as a Map.
cq = qb.createQuery(Object[].class);
from = cq.from(Employee.class);
cq.multiselect(from.alias("employee"), from.get("address").alias("address"), from.get("id").alias("id"));
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")), qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName"))));
query = em.createQuery(cq);
query.setHint(QueryHints.RESULT_TYPE, ResultType.Map);
query.setParameter("id", employee.getId());
query.setParameter("firstName", employee.getFirstName());
Map mapResult = (Map)query.getSingleResult();
if ((mapResult.size() != 3) ||(mapResult.get("employee") != employee) || (mapResult.get("address") != employee.getAddress()) || (!mapResult.get("id").equals(employee.getId()))) {
fail("Map result not correct: " + mapResult);
}
listResult = query.getResultList();
mapResult = (Map)listResult.get(0);
if ((mapResult.size() != 3) ||(mapResult.get("employee") != employee) || (mapResult.get("address") != employee.getAddress()) || (!mapResult.get("id").equals(employee.getId()))) {
fail("Map result not correct: " + mapResult);
}
// Test single object, as a Map.
cq = qb.createQuery(Object[].class);
from = cq.from(Employee.class);
cq.multiselect(from.get("id").alias("id"));
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")), qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName"))));
query = em.createQuery(cq);
query.setHint(QueryHints.RESULT_TYPE, ResultType.Map);
query.setParameter("id", employee.getId());
query.setParameter("firstName", employee.getFirstName());
mapResult = (Map)query.getSingleResult();
if ((mapResult.size() != 1) || (!mapResult.get("id").equals(employee.getId()))) {
fail("Map result not correct: " + mapResult);
}
listResult = query.getResultList();
mapResult = (Map)listResult.get(0);
if ((mapResult.size() != 1) || (!mapResult.get("id").equals(employee.getId()))) {
fail("Map result not correct: " + mapResult);
}
// Test single object, as an array.
cq = qb.createQuery(Employee.class);
from = cq.from(Employee.class);
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")), qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName"))));
query = em.createQuery(cq);
query.setHint(QueryHints.QUERY_TYPE, QueryType.Report);
query.setHint(QueryHints.RESULT_TYPE, ResultType.Array);
query.setParameter("id", employee.getId());
query.setParameter("firstName", employee.getFirstName());
arrayResult = (Object[])query.getSingleResult();
if (arrayResult[0] != employee) {
fail("Array result not correct: " + arrayResult);
}
// Test single object, as value.
cq = qb.createQuery(Object[].class);
from = cq.from(Employee.class);
cq.multiselect(from.get("id"));
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")), qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName"))));
query = em.createQuery(cq);
query.setParameter("id", employee.getId());
query.setParameter("firstName", employee.getFirstName());
Object valueResult = query.getSingleResult();
if (! valueResult.equals(employee.getId())) {
fail("Value result not correct: " + valueResult);
}
listResult = query.getResultList();
valueResult = listResult.get(0);
if (! valueResult.equals(employee.getId())) {
fail("Value result not correct: " + valueResult);
}
// Test multi object, as value.
cq = qb.createQuery(Object[].class);
from = cq.from(Employee.class);
cq.multiselect(from.get("id"), from.get("firstName"));
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")), qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName"))));
query = em.createQuery(cq);
query.setHint(QueryHints.RESULT_TYPE, ResultType.Value);
query.setParameter("id", employee.getId());
query.setParameter("firstName", employee.getFirstName());
valueResult = query.getSingleResult();
if (! valueResult.equals(employee.getId())) {
fail("Value result not correct: " + valueResult);
}
// Test single object, as attribute.
cq = qb.createQuery(Object[].class);
from = cq.from(Employee.class);
cq.multiselect(from.get("id"));
cq.where(qb.and(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")), qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName"))));
query = em.createQuery(cq);
query.setHint(QueryHints.RESULT_TYPE, ResultType.Attribute);
query.setParameter("id", employee.getId());
query.setParameter("firstName", employee.getFirstName());
valueResult = query.getSingleResult();
if (! valueResult.equals(employee.getId())) {
fail("Value result not correct: " + valueResult);
}
listResult = query.getResultList();
valueResult = listResult.get(0);
if (! valueResult.equals(employee.getId())) {
fail("Value result not correct: " + valueResult);
}
} finally {
rollbackTransaction(em);
}
}
/**
* Test that a cache hit will occur on a primary key query.
*/
public void testQueryExactPrimaryKeyCacheHits() {
EntityManager em = createEntityManager();
beginTransaction(em);
QuerySQLTracker counter = null;
try {
// Load an employee into the cache.
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery cq = qb.createQuery(Employee.class);
Query query = em.createQuery(cq);
List result = query.getResultList();
Employee employee = (Employee)result.get(0);
// Count SQL.
counter = new QuerySQLTracker(getServerSession());
// Query by primary key.
cq = qb.createQuery(Employee.class);
Root from = cq.from(Employee.class);
cq.where(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")));
query = em.createQuery(cq);
query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheByExactPrimaryKey);
query.setParameter("id", employee.getId());
Employee queryResult = (Employee)query.getSingleResult();
if (queryResult != employee) {
fail("Employees are not equal: " + employee + ", " + queryResult);
}
if (counter.getSqlStatements().size() > 0) {
fail("Cache hit do not occur: " + counter.getSqlStatements());
}
} finally {
rollbackTransaction(em);
if (counter != null) {
counter.remove();
}
}
}
public void testQueryHintFetch(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaQuery<Employee> cq = em.getCriteriaBuilder().createQuery(Employee.class);
CriteriaBuilder qb = em.getCriteriaBuilder();
Root<Employee> root = cq.from(em.getMetamodel().entity(Employee.class));
cq.where(qb.equal(root.get("firstName"), qb.literal("Bob")));
TypedQuery<Employee> tq = em.createQuery(cq);
tq.setHint(QueryHints.FETCH, "e.projects");
List<Employee> result = tq.getResultList();
assertFalse("No Employees were returned", result.isEmpty());
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
ObjectOutputStream stream = new ObjectOutputStream(byteStream);
stream.writeObject(result.get(0));
stream.flush();
byte arr[] = byteStream.toByteArray();
ByteArrayInputStream inByteStream = new ByteArrayInputStream(arr);
ObjectInputStream inObjStream = new ObjectInputStream(inByteStream);
Employee emp = (Employee) inObjStream.readObject();
assertTrue("Did not return Employee", emp.getClass().equals(Employee.class));
assertTrue("Employee had wrong firstname", emp.getFirstName().equalsIgnoreCase("bob"));
emp.getProjects().size(); //may cause exception
} catch (IOException e) {
fail("Failed during serialization");
} catch (ClassNotFoundException e) {
fail("Failed during serialization");
}
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
public void testProd(){
EntityManager em = createEntityManager();
beginTransaction(em);
try{
// em.createQuery("Select size(e.responsibilities) from Employee e").getResultList();
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<BigInteger> cquery = qbuilder.createQuery(BigInteger.class);
Root<Employee> customer = cquery.from(Employee.class);
cquery.select(qbuilder.toBigInteger(qbuilder.prod(qbuilder.literal(BigInteger.valueOf(5)),customer.<Integer>get("salary"))));
TypedQuery<BigInteger> tquery = em.createQuery(cquery);
List<BigInteger> result = tquery.getResultList();
for(BigInteger value : result){
assertTrue("Incorrect arithmatic returned ", value.mod(BigInteger.valueOf(5)).equals(BigInteger.valueOf(0)));
}
// No assert as version is not actually a mapped field in dealer.
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Test that a cache hit will occur on a query.
*/
public void testQueryCacheFirstCacheHits() {
EntityManager em = createEntityManager();
beginTransaction(em);
QuerySQLTracker counter = null;
try {
// Load an employee into the cache.
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery cq = qb.createQuery(Employee.class);
Query query = em.createQuery(cq);
List result = query.getResultList();
Employee employee = (Employee)result.get(result.size() - 1);
// Count SQL.
counter = new QuerySQLTracker(getServerSession());
// Query by primary key.
cq = qb.createQuery(Employee.class);
Root from = cq.from(Employee.class);
cq.where(qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName")));
query = em.createQuery(cq);
query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheThenDatabase);
query.setParameter("firstName", employee.getFirstName());
Employee queryResult = (Employee)query.getSingleResult();
if (!queryResult.getFirstName().equals(employee.getFirstName())) {
fail("Employees are not equal: " + employee + ", " + queryResult);
}
if (counter.getSqlStatements().size() > 0) {
fail("Cache hit do not occur: " + counter.getSqlStatements());
}
} finally {
rollbackTransaction(em);
if (counter != null) {
counter.remove();
}
}
}
/**
* Test that a cache hit will occur on a query.
*/
public void testQueryCacheOnlyCacheHits() {
EntityManager em = createEntityManager();
beginTransaction(em);
QuerySQLTracker counter = null;
try {
// Load an employee into the cache.
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery cq = qb.createQuery(Employee.class);
Query query = em.createQuery(cq);
List result = query.getResultList();
Employee employee = (Employee)result.get(result.size() - 1);
// Count SQL.
counter = new QuerySQLTracker(getServerSession());
// Query by primary key.
cq = qb.createQuery(Employee.class);
Root from = cq.from(Employee.class);
cq.where(qb.equal(from.get("firstName"), qb.parameter(from.get("firstName").getModel().getBindableJavaType(), "firstName")));
query = em.createQuery(cq);
query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
query.setParameter("firstName", employee.getFirstName());
// Test that list works as well.
query.getResultList();
if (counter.getSqlStatements().size() > 0) {
fail("Cache hit do not occur: " + counter.getSqlStatements());
}
} finally {
rollbackTransaction(em);
if (counter != null) {
counter.remove();
}
}
}
/**
* Test that a cache hit will occur on a query when the object is not in the unit of work/em.
*/
public void testQueryCacheOnlyCacheHitsOnSession() {
EntityManager em = createEntityManager();
beginTransaction(em);
QuerySQLTracker counter = null;
try {
// Load an employee into the cache.
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery cq = qb.createQuery(Employee.class);
Query query = em.createQuery(cq);
List result = query.getResultList();
Employee employee = (Employee)result.get(result.size() - 1);
// Count SQL.
counter = new QuerySQLTracker(getServerSession());
// Query by primary key.
rollbackTransaction(em);
closeEntityManager(em);
em = createEntityManager();
beginTransaction(em);
cq = qb.createQuery(Employee.class);
Root from = cq.from(Employee.class);
cq.where(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")));
query = em.createQuery(cq);
query.setHint(QueryHints.QUERY_TYPE, QueryType.ReadObject);
query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
query.setParameter("id", employee.getId());
if (query.getSingleResult() == null) {
fail("Query did not check session cache.");
}
if (counter.getSqlStatements().size() > 0) {
fail("Cache hit do not occur: " + counter.getSqlStatements());
}
rollbackTransaction(em);
closeEntityManager(em);
em = createEntityManager();
beginTransaction(em);
cq = qb.createQuery(Employee.class);
from = cq.from(Employee.class);
cq.where(qb.equal(from.get("id"), qb.parameter(from.get("id").getModel().getBindableJavaType(), "id")));
query = em.createQuery(cq);
query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
query.setParameter("id", employee.getId());
if (query.getResultList().size() != 1) {
fail("Query did not check session cache.");
}
if (counter.getSqlStatements().size() > 0) {
fail("Cache hit do not occur: " + counter.getSqlStatements());
}
} finally {
if (counter != null) {
counter.remove();
}
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* bug 413892: tests that unused inner join expressions from root.get("manager") do not affect explicit out joins
* created from root.join("manager").
*/
public void testUnusedJoinDoesNotAffectOtherJoins() {
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
Path pathToIgnore = customer.get("manager").get("address");
Join manager = customer.join("manager", JoinType.LEFT);
TypedQuery<Employee> tquery = em.createQuery(cquery);
List<Employee> result = tquery.getResultList();
assertFalse ("No results found", result.isEmpty());
long count = (Long)em.createQuery("Select count(e) from Employee e ").getSingleResult();
assertTrue("Incorrect number of results returned", result.size() == count);
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* bug 413892: tests that unused inner join expressions from root.get("manager") do not affect explicit outer joins
* created from root.fetch("manager").
*/
public void testUnusedJoinDoesNotAffectFetchJoin() {
EntityManager em = createEntityManager();
beginTransaction(em);
try{
CriteriaBuilder qbuilder = em.getCriteriaBuilder();
CriteriaQuery<Employee> cquery = qbuilder.createQuery(Employee.class);
Root<Employee> customer = cquery.from(Employee.class);
Path pathToIgnore = customer.get("manager").get("address");
customer.fetch("manager", JoinType.LEFT);
TypedQuery<Employee> tquery = em.createQuery(cquery);
List<Employee> result = tquery.getResultList();
assertFalse ("No results found", result.isEmpty());
long count = (Long)em.createQuery("Select count(e) from Employee e ").getSingleResult();
assertTrue("Incorrect number of results returned", result.size() == count);
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Bug 464833 - Criteria API: calling getRestriction() on a query returns Predicate with incorrect expression
* An incorrect expression is observed when calling getRestriction() on an existing query to obtain an existing Predicate.
* Tests: Validate that an existing Predicate (obtained with criteriaQuery.getRestriction()) has correct child expressions.
*/
public void testGetRestrictionReturningCorrectPredicate() {
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<Employee> criteriaQuery = builder.createQuery(Employee.class);
Root<Employee> root = criteriaQuery.from(Employee.class);
// simple case - construct a predicate
criteriaQuery.where(builder.equal(root.get("firstName"), "Bob"));
TypedQuery<Employee> query1 = em.createQuery(criteriaQuery);
List<Employee> results1 = query1.getResultList();
long count1 = (Long)em.createQuery("select count(e) from Employee e where e.firstName = 'Bob'").getSingleResult();
// validate the expressions on the Predicate returned from CriteriaQuery getRestriction()
Predicate predicate = criteriaQuery.getRestriction();
// for the current example, the Predicate returned is expected to be a CompoundExpressionImpl
assertNotNull("Predicate should be non-null", predicate);
assertTrue("Invalid predicate type returned: " + predicate.getClass().getName(), predicate instanceof CompoundExpressionImpl);
CompoundExpressionImpl compoundExpression = (CompoundExpressionImpl)predicate;
// The where has two child expressions representing:
// 1) a path (query key) for "firstName" and 2) an expression (constant) for "Bob".
List<Expression<?>> expressions = compoundExpression.getChildExpressions();
assertSame("Predicate should have two child expressions", 2, expressions.size());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
/**
* Test that checks duplicating of joins
*/
public void testJoinDuplication() throws NoSuchFieldException, IllegalAccessException {
EntityManager em = createEntityManager();
beginTransaction(em);
try {
CriteriaBuilder qb = em.getCriteriaBuilder();
CriteriaQuery<Employee>cq = qb.createQuery(Employee.class);
Root<Employee> root = cq.from(Employee.class);
root.join("manager");
em.createQuery(cq);
Field field = cq.getClass().getDeclaredField("joins");
field.setAccessible(true);
Set<FromImpl> value = (Set<FromImpl>) field.get(cq);
assertEquals(1, value.size());
em.createQuery(cq);
((CriteriaQueryImpl<Employee>)cq).translate();
value = (Set<FromImpl>) field.get(cq);
assertEquals(1, value.size());
} finally {
rollbackTransaction(em);
closeEntityManager(em);
}
}
}