blob: 5dc1265be1a9d12e27c98c4bc09c300eb02b9d4f [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:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.jpa.jpql;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import jakarta.persistence.Parameter;
import junit.framework.Test;
import junit.framework.TestSuite;
import jakarta.persistence.Query;
import jakarta.persistence.EntityManager;
import org.eclipse.persistence.testing.models.jpa.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.advanced.Jigsaw;
import org.eclipse.persistence.testing.models.jpa.advanced.JigsawPiece;
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.config.CacheUsage;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.testing.models.jpa.advanced.AdvancedTableCreator;
/**
* <p>
* <b>Purpose</b>: Test EJBQL parameter 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 EJBQL parameter functionality
* </ul>
* @see org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator
* @see JUnitDomainObjectComparer
*/
public class JUnitJPQLParameterTestSuite extends JUnitTestCase {
static JUnitDomainObjectComparer comparer; //the global comparer object used in all tests
public JUnitJPQLParameterTestSuite()
{
super();
}
public JUnitJPQLParameterTestSuite(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("JUnitJPQLParameterTestSuite");
suite.addTest(new JUnitJPQLParameterTestSuite("testSetup"));
suite.addTest(new JUnitJPQLParameterTestSuite("multipleParameterTest"));
suite.addTest(new JUnitJPQLParameterTestSuite("updateEnumParameter"));
suite.addTest(new JUnitJPQLParameterTestSuite("testQueryParametersCheckCacheTest"));
suite.addTest(new JUnitJPQLParameterTestSuite("testQueryParametersDontCheckCacheTest"));
suite.addTest(new JUnitJPQLParameterTestSuite("testQueryParametersReversedCheckCacheTest"));
suite.addTest(new JUnitJPQLParameterTestSuite("testQueryParametersReversedDontCheckCacheTest"));
if (! JUnitTestCase.isJPA10()) {
suite.addTest(new JUnitJPQLParameterTestSuite("emptyParametersForNonParameterizedNamedQueryTest"));
}
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);
}
//Test case for selecting employee from the database using parameters
public void multipleParameterTest()
{
EntityManager em = createEntityManager();
Employee employee = (Employee) (getServerSession().readAllObjects(Employee.class).firstElement());
Vector expectedResult = new Vector();
expectedResult.add(employee);
Query query = em.createQuery("SELECT OBJECT(emp) FROM Employee emp WHERE emp.firstName = ?1 AND emp.id = ?3");
query.setParameter(1, employee.getFirstName());
query.setParameter(3, employee.getId());
List result = query.getResultList();
assertTrue("Multiple Parameter Test Case Failed", comparer.compareObjects(result, expectedResult));
}
// Test for GF#1123 - UPDATE with JPQL does not handle enums correctly.
public void updateEnumParameter() {
if ((JUnitTestCase.getServerSession()).getPlatform().isSymfoware()) {
getServerSession().logMessage("Test updateEnumParameter skipped for this platform, "
+ "Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
return;
}
EntityManager em = createEntityManager();
int nrOfEmps = executeJPQLReturningInt(
em, "SELECT COUNT(e) FROM Employee e WHERE e.period.endDate IS NULL");
// test query
String update = "UPDATE Employee e SET e.status = :status, e.payScale = :payScale WHERE e.period.endDate IS NULL";
beginTransaction(em);
try {
Query q = em.createQuery(update);
q.setParameter("status", Employee.EmployeeStatus.FULL_TIME);
q.setParameter("payScale", Employee.SalaryRate.SENIOR);
int updated = q.executeUpdate();
assertEquals("wrong number of updated instances", nrOfEmps, updated);
// check database changes
Query q2 = em.createQuery(
"SELECT COUNT(e) FROM Employee e WHERE e.period.endDate IS NULL AND e.status = :status AND e.payScale = :payScale");
q2.setParameter("status", Employee.EmployeeStatus.FULL_TIME);
q2.setParameter("payScale", Employee.SalaryRate.SENIOR);
int nr = ((Number)q2.getSingleResult()).intValue();
assertEquals("unexpected number of changed values in the database", nrOfEmps, nr);
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
}
}
/** Helper method executing a JPQL query retuning an int value. */
private int executeJPQLReturningInt(EntityManager em, String jpql)
{
Query q = em.createQuery(jpql);
Object result = q.getSingleResult();
return ((Number)result).intValue();
}
// Bug 344492
public void emptyParametersForNonParameterizedNamedQueryTest() {
EntityManager em = createEntityManager();
assertNotNull(em);
Query query = em.createNamedQuery("findAllEmployeesOrderById");
assertNotNull(query);
Set<Parameter<?>> parameters = query.getParameters();
assertNotNull(parameters);
assertEquals("Parameters size should be 0", 0, parameters.size());
}
public void testQueryParametersCheckCacheTest() {
testQueryParametersWithQueryAndCheckCache("SELECT p FROM JigsawPiece p, Jigsaw j WHERE j.id=:jigsawId AND p.id=:jigsawPieceId", true);
}
public void testQueryParametersDontCheckCacheTest() {
testQueryParametersWithQueryAndCheckCache("SELECT p FROM JigsawPiece p, Jigsaw j WHERE j.id=:jigsawId AND p.id=:jigsawPieceId", false);
}
public void testQueryParametersReversedCheckCacheTest() {
testQueryParametersWithQueryAndCheckCache("SELECT p FROM JigsawPiece p, Jigsaw j WHERE p.id=:jigsawPieceId AND j.id=:jigsawId", true);
}
public void testQueryParametersReversedDontCheckCacheTest() {
testQueryParametersWithQueryAndCheckCache("SELECT p FROM JigsawPiece p, Jigsaw j WHERE p.id=:jigsawPieceId AND j.id=:jigsawId", false);
}
// EL bug 430042 - pk query parameter binding incorrect
private void testQueryParametersWithQueryAndCheckCache(String jpqlQueryString, boolean checkCacheOnly) {
EntityManager em = createEntityManager();
Jigsaw jigsawTestData = null;
JigsawPiece jigsawPieceTestData = null;
try {
beginTransaction(em);
jigsawTestData = new Jigsaw();
jigsawPieceTestData = new JigsawPiece();
jigsawTestData.addPiece(jigsawPieceTestData);
em.persist(jigsawTestData);
commitTransaction(em);
closeEntityManager(em);
em = createEntityManager();
Query query = em.createQuery(jpqlQueryString);
query.setParameter("jigsawId", jigsawTestData.getId());
query.setParameter("jigsawPieceId", jigsawPieceTestData.getId());
if (checkCacheOnly) {
query.setHint(QueryHints.CACHE_USAGE, CacheUsage.CheckCacheOnly);
}
JigsawPiece resultPiece = (JigsawPiece) query.getSingleResult();
assertNotNull("Query Entity should not be null", resultPiece);
Jigsaw resultJigsaw = resultPiece.getJigsaw();
assertNotNull("Queried Entity's parent reference should not be null", resultJigsaw);
assertEquals("Queried Entity should have the same id", jigsawPieceTestData.getId(), resultPiece.getId());
assertEquals("Queried Entity should reference the same parent Entity", jigsawTestData.getId(), resultJigsaw.getId());
} finally {
if (jigsawTestData != null) {
beginTransaction(em);
Jigsaw jigsawToRemove = em.find(Jigsaw.class, jigsawTestData.getId());
em.remove(jigsawToRemove);
for (JigsawPiece piece : jigsawToRemove.getPieces()) {
em.remove(piece);
}
commitTransaction(em);
}
closeEntityManager(em);
}
}
}