| /* |
| * 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); |
| } |
| } |
| |
| } |