/******************************************************************************* | |
* Copyright (c) 1998, 2014 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 v1.0 and Eclipse Distribution License v. 1.0 | |
* which accompanies this distribution. | |
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html | |
* and the Eclipse Distribution License is available at | |
* http://www.eclipse.org/org/documents/edl-v10.php. | |
* | |
* Contributors: | |
* Oracle - initial API and implementation from Oracle TopLink | |
******************************************************************************/ | |
package org.eclipse.persistence.testing.tests.jpa.jpql; | |
import java.util.Arrays; | |
import java.util.List; | |
import java.util.Set; | |
import java.util.Vector; | |
import junit.framework.Test; | |
import junit.framework.TestSuite; | |
import javax.persistence.Query; | |
import javax.persistence.EntityManager; | |
import org.eclipse.persistence.testing.models.jpa.advanced.Address; | |
import org.eclipse.persistence.testing.models.jpa.advanced.Department; | |
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.PhoneNumber; | |
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; | |
import org.eclipse.persistence.testing.models.relationshipmaintenance.Dept; | |
/** | |
* <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 | |
public void setUp() | |
{ | |
} | |
//This method is run at the end of EVERY test case method | |
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 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); | |
} | |
} | |
} |