blob: 1ca9a262ef5c7cf67de95efa22d98da081b3a92b [file] [log] [blame]
/*
* Copyright (c) 2018, 2021 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2021 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:
// 02/20/2018-2.7 Will Dazey
// - 531062: Incorrect expression type created for CollectionExpression
// 05/11/2018-2.7 Will Dazey
// - 534515: Incorrect return type set for CASE functions
package org.eclipse.persistence.jpa.test.jpql;
import java.util.ArrayList;
import java.util.List;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import org.eclipse.persistence.internal.jpa.EntityManagerFactoryImpl;
import org.eclipse.persistence.jpa.test.framework.DDLGen;
import org.eclipse.persistence.jpa.test.framework.Emf;
import org.eclipse.persistence.jpa.test.framework.EmfRunner;
import org.eclipse.persistence.jpa.test.jpql.model.JPQLEmbeddedValue;
import org.eclipse.persistence.jpa.test.jpql.model.JPQLEntity;
import org.eclipse.persistence.jpa.test.jpql.model.JPQLEntityId;
import org.eclipse.persistence.jpa.test.jpql.model.OtherSubClass;
import org.eclipse.persistence.jpa.test.jpql.model.QueryResult;
import org.eclipse.persistence.jpa.test.jpql.model.SimpleEntity;
import org.eclipse.persistence.jpa.test.jpql.model.SubClass;
import org.eclipse.persistence.jpa.test.jpql.model.SuperClass;
import org.eclipse.persistence.platform.database.DatabasePlatform;
import org.eclipse.persistence.platform.database.DerbyPlatform;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(EmfRunner.class)
public class TestComplexJPQL {
@Emf(name = "inEMF", createTables = DDLGen.DROP_CREATE, classes = { JPQLEntity.class, JPQLEntityId.class, JPQLEmbeddedValue.class })
private EntityManagerFactory inEMF;
@Emf(name = "caseEMF", createTables = DDLGen.DROP_CREATE, classes = { SimpleEntity.class })
private EntityManagerFactory caseEMF;
@Emf(name = "joinEMF", createTables = DDLGen.DROP_CREATE, classes = { SubClass.class, SuperClass.class, OtherSubClass.class })
private EntityManagerFactory joinEMF;
@Test
public void testINWithSubquery() {
DatabasePlatform platform = getPlatform(inEMF);
Assume.assumeFalse("Test will not run on " + platform + ". " + platform + " does "
+ "not support multiple IN clause for prepared statements.", platform instanceof DerbyPlatform);
EntityManager em = inEMF.createEntityManager();
try {
Query q = em.createQuery("select t0.id from JPQLEntity t0 "
+ "where (t0.string1, t0.string2) "
+ "in (select t1.string1, t1.string2 from JPQLEntity t1)");
q.getResultList();
} finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
}
@Test
public void test_IN_ClauseLimit() {
EntityManager em = inEMF.createEntityManager();
try {
Query q = em.createQuery("select t0.id from JPQLEntity t0 "
+ "where t0.id.value1.value <> :parameterString and t0.string1 in :parameterList");
//Create a list longer than the limit
int limit = getPlatform(inEMF).getINClauseLimit() + 10;
List<String> parameterList = new ArrayList<String>();
for(int p = 0; p < limit; p++) {
parameterList.add("" + p);
}
q.setParameter("parameterList", parameterList);
q.setParameter("parameterString", "Test");
q.getResultList();
} finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
}
@Test
public void test_NOTIN_ClauseLimit() {
EntityManager em = inEMF.createEntityManager();
try {
Query q = em.createQuery("select t0.id from JPQLEntity t0 "
+ "where t0.id.value1.value <> :parameterString and t0.string1 not in :parameterList");
//Create a list longer than the limit
int limit = getPlatform(inEMF).getINClauseLimit() + 10;
List<String> parameterList = new ArrayList<String>();
for(int p = 0; p < limit; p++) {
parameterList.add("" + p);
}
q.setParameter("parameterList", parameterList);
q.setParameter("parameterString", "Test");
q.getResultList();
} finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
}
@Test
public void testComplexJPQLCase() {
EntityManager em = caseEMF.createEntityManager();
try {
em.getTransaction().begin();
SimpleEntity tbl1 = new SimpleEntity();
tbl1.setKeyString("Key01");
tbl1.setItemString1("A");
tbl1.setItemString2("B");
tbl1.setItemString3("C");
tbl1.setItemString4("D");
tbl1.setItemInteger1(1);
em.persist(tbl1);
SimpleEntity tbl2 = new SimpleEntity();
tbl2.setKeyString("Key02");
tbl2.setItemString1("A");
tbl2.setItemString2("B");
tbl2.setItemString3("C");
tbl2.setItemString4("D");
tbl2.setItemInteger1(2);
em.persist(tbl2);
em.getTransaction().commit();
TypedQuery<QueryResult> q = em.createQuery("SELECT new org.eclipse.persistence.jpa.test.jpql.model.QueryResult("
+ "s.itemString1, "
+ "CASE s.itemString2 WHEN 'J' THEN 'Japan' ELSE 'Other' END, "
+ "SUM(CASE WHEN s.itemString3 = 'C' THEN 1 ELSE 0 END), "
+ "SUM(CASE WHEN s.itemString4 = 'D' THEN 1 ELSE 0 END) ) "
+ "FROM SimpleEntity s "
+ "GROUP BY s.itemString1, s.itemString2", QueryResult.class);
q.getResultList();
} finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
}
/**
* Tests EclipseLink's parsing of a LEFT OUTER JOIN when the condition has no matches.
* EclipseLink should account for the NULL values in the right table.<br>
* see Bug 493804
*/
@Test
public void testLeftOuterJoinWithNullResult() {
EntityManager em = joinEMF.createEntityManager();
try {
em.getTransaction().begin();
SubClass t = new SubClass("Sub1");
em.persist(t);
t = new SubClass("Sub2");
em.persist(t);
OtherSubClass t2 = new OtherSubClass("OtherSub1");
em.persist(t2);
t2 = new OtherSubClass("OtherSub2");
em.persist(t2);
//Populate
em.getTransaction().commit();
Query q = em.createQuery("SELECT sub1, sub2 from SubClass sub1 LEFT JOIN SubClass sub2 ON sub2.name = 'unknown'");
List<?> result = q.getResultList();
Assert.assertEquals("The result size returned was incorrect", 2, result.size());
} finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
}
private static DatabasePlatform getPlatform(EntityManagerFactory emf) {
return ((EntityManagerFactoryImpl)emf).getServerSession().getPlatform();
}
}