blob: 21afedc4f17a5955db21e193c0757f497154f1e8 [file] [log] [blame]
/*
* Copyright (c) 2008, 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:
// Chris Delahunt - testing for native queries
// - Bug299926: Case insensitive table / column matching with native SQL queries
package org.eclipse.persistence.testing.tests.jpa.jpql;
import java.util.List;
import jakarta.persistence.EntityManager;
import jakarta.persistence.Query;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.framework.JoinedAttributeTestHelper;
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.GoldBuyer;
import org.eclipse.persistence.testing.models.jpa.advanced.NativeQueryTableCreator;
import org.eclipse.persistence.testing.models.jpa.advanced.EmployeePopulator;
import org.eclipse.persistence.testing.tests.jpa.advanced.NamedNativeQueryJUnitTest;
/**
* @author cdelahun
*
*/
public class JUnitNativeQueryTestSuite extends JUnitTestCase {
protected String PUName;
public JUnitNativeQueryTestSuite() {
super();
if (isOnServer()) {
PUName = "MulitPU-1";
} else {
PUName = "default";
}
}
public JUnitNativeQueryTestSuite(String name) {
super(name);
if (isOnServer()) {
PUName = "MulitPU-1";
} else {
PUName = "default";
}
}
public static Test suite() {
TestSuite suite = new TestSuite();
suite.setName("NativeQueryTestSuite");
suite.addTest(new JUnitNativeQueryTestSuite("testSetup"));
//Removed for 299926
suite.addTest(new JUnitNativeQueryTestSuite("testNativeQueryWithMixedCaseFields"));
suite.addTest(new JUnitNativeQueryTestSuite("testNativeQueryHint"));
suite.addTest(new JUnitNativeQueryTestSuite("testCaseSensitivity_GoldBuyer1"));
suite.addTest(new JUnitNativeQueryTestSuite("testNativeQueryCacheHit"));
//This suite uses the same setup as this one
TestSuite NamedNativeQuerySuite = new TestSuite();
suite.addTest(NamedNativeQueryJUnitTest.addNamedNativeQueryTests(NamedNativeQuerySuite));
return suite;
}
/**
* The setup is done as a test, both to record its failure, and to allow execution in the server.
*/
public void testSetup() {
DatabaseSession session = JUnitTestCase.getServerSession(PUName);
//create a new EmployeePopulator
EmployeePopulator employeePopulator = new EmployeePopulator();
new NativeQueryTableCreator().replaceTables(session);
//Populate the tables
employeePopulator.buildExamples();
//Persist the examples in the database
employeePopulator.persistExample(session);
clearCache(PUName);
}
/**
* 334704 - native queries do not use the shared cache
*/
public void testNativeQueryCacheHit() {
Address result = null;
EntityManager em = createEntityManager(PUName);
Query query = em.createQuery("Select a from Address a");
Address a = (Address)query.getResultList().get(0);
closeEntityManager(em);
//test needs to use a new EM so that the object returned is from the shared cache.
em = createEntityManager(PUName);
try {
this.beginTransaction(em);
query = em.createNativeQuery("Select ADDRESS_ID from CMP3_ADDRESS where ADDRESS_ID="+a.getID(), Address.class);
result = (Address)query.getSingleResult();
} finally {
rollbackTransaction(em);
clearCache(PUName);
closeEntityManager(em);
}
assertTrue("Street from Address read using native query did not match the cache version", result.getStreet()!=null && result.getStreet().equals(a.getStreet()));
}
/* Removed for 299926 when the default changed to false.
* force results to be returned in camel case - any case that is different from what is defined in the Entity's field definitions
*/
public void testNativeQueryWithMixedCaseFields() {
EntityManager em = createEntityManager(PUName);
try {
Address expectedAddress = (Address)em.createQuery("select a from Address a").getResultList().get(0);
Address returnedAddress = null;
ServerSession session = JUnitTestCase.getServerSession();
String delimiter = session.getPlatform().getStartDelimiter();
Query q = em.createNativeQuery(
"Select ADDRESS_ID as " + delimiter + "aDdReSs_iD" +delimiter +
", P_CODE as "+ delimiter + "P_cOdE" +delimiter +
", STREET as "+ delimiter + "StReeT" +delimiter +
", PROVINCE as "+ delimiter + "PrOvInCe" +delimiter +
", TYPE as " + delimiter + "TyPe" +delimiter +
", CITY as " + delimiter + "CiTy" +delimiter +
", COUNTRY as " + delimiter + "CoUnTrY" +delimiter +
", VERSION as " + delimiter + "VeRsIoN" +delimiter +
" from CMP3_ADDRESS where ADDRESS_ID = "+expectedAddress.getID()
, Address.class
);
returnedAddress = (Address)q.getSingleResult();
assertNotNull("no address returned",returnedAddress);
assertTrue("returned address does not match the expected address", session.compareObjects(returnedAddress, expectedAddress));
//this query uses a resultsetmapping that looks for columns as camel case.
q = em.createNativeQuery(
"Select ADDRESS_ID"/* as " + delimiter + "aDrEsS_iD" +delimiter*/ +
", P_CODE"/* as "+ delimiter + "P_cOdE" +delimiter*/ +
", STREET"/* as "+ delimiter + "StReeT" +delimiter*/ +
", PROVINCE"/* as "+ delimiter + "PrOvInCe" +delimiter*/ +
", TYPE"/* as " + delimiter + "TyPe" +delimiter*/ +
", CITY"/* as " + delimiter + "CiTy" +delimiter*/ +
", COUNTRY"/* as " + delimiter + "CoUnTy" +delimiter*/ +
", VERSION"/* as " + delimiter + "VeRsIoN" +delimiter*/ +
" from CMP3_ADDRESS where ADDRESS_ID = "+expectedAddress.getID()
, "address-case-sensitive-map"
);
returnedAddress = (Address)q.getSingleResult();
assertNotNull("no address returned",returnedAddress);
assertTrue("returned address does not match the expected address", session.compareObjects(returnedAddress, expectedAddress));
} finally {
closeEntityManager(em);
}
}
// Test that hints work for native queries.
public void testNativeQueryHint() {
EntityManager em = createEntityManager(PUName);
Query query = em.createNativeQuery("Select * from CMP3_ADDRESS");
query.setHint("somehint", "whatever");
query.setHint(QueryHints.BIND_PARAMETERS, "false");
query.getResultList();
clearCache(PUName);
closeEntityManager(em);
}
/**tests the SQL used for a JPQL query against native sql query.
* It tests that the "Descrip" field name defined is sent to the database in JPQL (Will fail on case sensitive database if not)
* And tests that the "Descrip" field is found and populated into GoldBuyer when using JPQL
*/
public void testCaseSensitivity_GoldBuyer1() {
EntityManager em = createEntityManager(PUName);
ServerSession session = JUnitTestCase.getServerSession(PUName);
Query jpaquery = em.createQuery("Select b from GoldBuyer b");
List<GoldBuyer> jpaQueryResults = jpaquery.getResultList();
closeEntityManager(em);
// clear cache
clearCache(PUName);
em = createEntityManager(PUName);
Query query = em.createNativeQuery("Select * from CMP3_BUYER WHERE (DTYPE = 'GoldBuyer')", GoldBuyer.class);
List<GoldBuyer> nativeQueryResults = query.getResultList();
closeEntityManager(em);
clearCache(PUName);
if (nativeQueryResults.isEmpty() ||
nativeQueryResults.get(0).getDescription() == null || nativeQueryResults.get(0).getDescription().length()==0 ) {
fail("testCaseSensitivity_GoldBuyer1 failed to return ");
}
String errorMsg = JoinedAttributeTestHelper.compareCollections(jpaQueryResults, nativeQueryResults, session.getClassDescriptor(GoldBuyer.class), session);
// non-empty error message means the test has failed
if(errorMsg.length() > 0) {
fail(errorMsg);
}
}
public void testCaseSensitivity2() {
EntityManager em = createEntityManager(PUName);
Query query = em.createNativeQuery("Select * from CMP3_ADDRESS");
query.setHint("somehint", "whatever");
query.setHint(QueryHints.BIND_PARAMETERS, "false");
query.getResultList();
closeEntityManager(em);
}
}