blob: 77b2d40609c33308b99ebfc1a1e41788b805ce99 [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
// 03/03/2010 - 2.1 Michael O'Brien
// - 302316: clear the object cache when testing stored procedure returns on SQLServer
// to avoid false positives visible only when debugging in DatabaseCall.buildOutputRow()
// - 260263: SQLServer 2005/2008 requires stored procedure creation select clause variable and column name matching
// 05/03/2009-1.2.1 Guy Pelletier
// - 307547: Exception in order by clause after migrating to eclipselink 1.2 release
package org.eclipse.persistence.testing.tests.jpa.fieldaccess.advanced;
import java.util.Collection;
import jakarta.persistence.LockModeType;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceException;
import jakarta.persistence.Query;
import junit.framework.*;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.internal.jpa.EJBQueryImpl;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Address;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.AdvancedTableCreator;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Department;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Employee;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.EmployeePopulator;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Equipment;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.EquipmentCode;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.GoldBuyer;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.PhoneNumber;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.LargeProject;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.Project;
import org.eclipse.persistence.testing.models.jpa.fieldaccess.advanced.SmallProject;
/**
* This test suite tests EclipseLink JPA annotations extensions.
*/
public class AdvancedJPAJunitTest extends JUnitTestCase {
private static int empId;
private static int penelopeId;
private static int deptId;
private static int buyerId;
private static long visa = 1234567890;
private static long amex = 1987654321;
private static long diners = 1192837465;
private static long mastercard = 1647382910;
private static String newResponsibility = "The most useless responsibility ever.";
public AdvancedJPAJunitTest() {
super();
}
public AdvancedJPAJunitTest(String name) {
super(name);
}
@Override
public void setUp() {
super.setUp();
clearCache("fieldaccess");
}
public static Test suite() {
TestSuite suite = new TestSuite();
suite.setName("AdvancedJPAJunitTest (fieldaccess)");
suite.addTest(new AdvancedJPAJunitTest("testSetup"));
suite.addTest(new AdvancedJPAJunitTest("testJoinFetchAnnotation"));
suite.addTest(new AdvancedJPAJunitTest("testVerifyEmployeeCustomizerSettings"));
suite.addTest(new AdvancedJPAJunitTest("testVerifyEmployeeManagerMappings"));
suite.addTest(new AdvancedJPAJunitTest("testUpdateEmployee"));
suite.addTest(new AdvancedJPAJunitTest("testVerifyUpdatedEmployee"));
suite.addTest(new AdvancedJPAJunitTest("testCreateNewBuyer"));
suite.addTest(new AdvancedJPAJunitTest("testVerifyNewBuyer"));
suite.addTest(new AdvancedJPAJunitTest("testBuyerOptimisticLocking"));
suite.addTest(new AdvancedJPAJunitTest("testGiveFredAnObjectTypeConverterChange"));
suite.addTest(new AdvancedJPAJunitTest("testUpdatePenelopesPhoneNumberStatus"));
suite.addTest(new AdvancedJPAJunitTest("testRemoveJillWithPrivateOwnedPhoneNumbers"));
suite.addTest(new AdvancedJPAJunitTest("testCreateNewEquipment"));
suite.addTest(new AdvancedJPAJunitTest("testAddNewEquipmentToDepartment"));
suite.addTest(new AdvancedJPAJunitTest("testRemoveDepartmentWithPrivateOwnedEquipment"));
suite.addTest(new AdvancedJPAJunitTest("testUpdateReadOnlyEquipmentCode"));
suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQuery"));
suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQueryInOut"));
suite.addTest(new AdvancedJPAJunitTest("testNamedStoredProcedureQueryWithRawData"));
suite.addTest(new AdvancedJPAJunitTest("testTransientConstructorSetFields"));
suite.addTest(new AdvancedJPAJunitTest("testPessimisticLockingNamedQuery"));
return suite;
}
/**
* The setup is done as a test, both to record its failure, and to allow execution in the server.
*/
public void testSetup() {
ServerSession session = JUnitTestCase.getServerSession("fieldaccess");
new AdvancedTableCreator().replaceTables(session);
// The EquipmentCode class 'should' be set to read only. We want
// to be able to create a couple in the Employee populator, so
// force the read only to false. If EquipmentCode is not
// actually read only, don't worry, we set the original read
// only value back on the descriptor and the error will be
// caught in a later test in this suite.
ClassDescriptor descriptor = session.getDescriptor(EquipmentCode.class);
boolean shouldBeReadOnly = descriptor.shouldBeReadOnly();
descriptor.setShouldBeReadOnly(false);
// Populate the database with our examples.
EmployeePopulator employeePopulator = new EmployeePopulator();
employeePopulator.buildExamples();
employeePopulator.persistExample(session);
descriptor.setShouldBeReadOnly(shouldBeReadOnly);
clearCache("fieldaccess");
}
/** test for bug 292385 - Transient fields not initialized for Entities */
public void testTransientConstructorSetFields(){
EntityManager em = createEntityManager("fieldaccess");
Project project = new Project();
LargeProject lproject = new LargeProject();
SmallProject sproject = new SmallProject();
project.setName("TCSetFieldsProject");
lproject.setName("TCSetFieldsLProject");
sproject.setName("TCSetFieldsSProject");
beginTransaction(em);
project = em.merge(project);
lproject = em.merge(lproject);
sproject = em.merge(sproject);
assertTrue("Project's default constructor wasn't used to create merged entity", project.getFieldOnlySetThroughConstructor()==1);
assertTrue("LargeProject's default constructor wasn't used to create merged entity", lproject.getFieldOnlySetThroughConstructor()==2);
assertTrue("Project's default constructor wasn't used to create merged SmallProject", sproject.getFieldOnlySetThroughConstructor()==1);
try{
em.flush();
this.commitTransaction(em);
closeEntityManager(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
em = createEntityManager("fieldaccess");
project = em.find(Project.class, project.getId());
lproject = em.find(LargeProject.class, lproject.getId());
sproject = em.find(SmallProject.class, sproject.getId());
closeEntityManager(em);
assertTrue("Project's default constructor wasn't used to create managed entity", project.getFieldOnlySetThroughConstructor()==1);
assertTrue("LargeProject's default constructor wasn't used to create managed entity", lproject.getFieldOnlySetThroughConstructor()==2);
assertTrue("Project's default constructor wasn't used to create managed SmallProject", sproject.getFieldOnlySetThroughConstructor()==1);
}
/**
* Verifies that settings from the EmployeeCustomizer have been set.
*/
public void testVerifyEmployeeCustomizerSettings() {
EntityManager em = createEntityManager("fieldaccess");
ClassDescriptor descriptor = getServerSession("fieldaccess").getDescriptorForAlias("Employee");
if (descriptor == null) {
fail("A descriptor for the Employee alias was not found.");
} else {
assertFalse("Disable cache hits was true. Customizer should have made it false.", descriptor.shouldDisableCacheHits());
}
closeEntityManager(em);
}
/**
* Bug 307547: Verifies that a mapping is not omitted from the descriptor after metadata processing.
*/
public void testVerifyEmployeeManagerMappings() {
EntityManager em = createEntityManager("fieldaccess");
ClassDescriptor descriptor = getServerSession("fieldaccess").getDescriptorForAlias("Employee");
if (descriptor == null) {
fail("A descriptor for the Employee alias was not found.");
} else {
assertNotNull("The isManager mapping was not found on the Employee descriptor.", descriptor.getMappingForAttributeName("isManager"));
assertNotNull("The getManager mapping was not found on the Employee descriptor.", descriptor.getMappingForAttributeName("getManager"));
assertNotNull("The setManager mapping was not found on the Employee descriptor.", descriptor.getMappingForAttributeName("setManager"));
}
closeEntityManager(em);
}
/**
* Verifies that the join-fetch annotation was read correctly.
*/
public void testJoinFetchAnnotation() {
ServerSession session = JUnitTestCase.getServerSession("fieldaccess");
ClassDescriptor descriptor = session.getDescriptor(Employee.class);
if (((ForeignReferenceMapping)descriptor.getMappingForAttributeName("department")).getJoinFetch() != ForeignReferenceMapping.OUTER_JOIN) {
fail("JoinFetch annotation not read correctly for Employee.department.");
}
}
/**
* Tests:
* - BasicCollection mapping
* - Serialized Basic of type EnumSet.
* - BasicCollection that uses an Enum converter (by detection).
*/
public void testUpdateEmployee() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
EJBQueryImpl query = (EJBQueryImpl) em.createNamedQuery("findAllFieldAccessSQLEmployees");
Collection<Employee> employees = query.getResultCollection();
if (employees.isEmpty()) {
fail("No Employees were found. Test requires at least one Employee to be created in the EmployeePopulator.");
} else {
Employee emp = employees.iterator().next();
emp.addResponsibility(newResponsibility);
emp.setMondayToFridayWorkWeek();
empId = emp.getId();
commitTransaction(em);
}
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Verifies:
* - a BasicCollection mapping.
* - a BasicCollection that uses an Enum converter (by detection).
*/
public void testVerifyUpdatedEmployee() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
Employee emp = em.find(Employee.class, empId);
assertNotNull("The updated employee was not found.", emp);
boolean found = false;
for (String responsibility : (Collection<String>) emp.getResponsibilities()) {
if (responsibility.equals(newResponsibility)) {
found = true;
break;
}
}
commitTransaction(em);
assertTrue("The new responsibility was not added.", found);
assertTrue("The basic collection using enums was not persisted correctly.", emp.worksMondayToFriday());
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests:
* - BasicMap mapping with a TypeConverter on the map value and an
* ObjectTypeConverter on the map key.
* - Basic with a custom converter
* - Serialized Basic of type EnumSet.
*/
public void testCreateNewBuyer() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
GoldBuyer buyer = new GoldBuyer();
buyer.setName("Guy Pelletier");
buyer.setGender("Made of testosterone");
buyer.setDescription("Loves to spend");
buyer.addVisa(visa);
buyer.addAmex(amex);
buyer.addDinersClub(diners);
buyer.addMastercard(mastercard);
buyer.setSaturdayToSundayBuyingDays();
em.persist(buyer);
commitTransaction(em);
buyerId = buyer.getId();
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Verifies:
* - BasicMap mapping with a TypeConverter on the map value and an
* ObjectTypeConverter on the map key.
* - Basic with a custom converter
* - Serialized Basic of type EnumSet.
*/
public void testVerifyNewBuyer() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
GoldBuyer buyer = em.find(GoldBuyer.class, buyerId);
assertNotNull("The new buyer was not found", buyer);
assertTrue("Gender was not persisted correctly.", buyer.isMale());
assertTrue("Visa card did not persist correctly.", buyer.hasVisa(visa));
assertTrue("Amex card did not persist correctly.", buyer.hasAmex(amex));
assertTrue("Diners Club card did not persist correctly.", buyer.hasDinersClub(diners));
assertTrue("Mastercard card did not persist correctly.", buyer.hasMastercard(mastercard));
assertTrue("The serialized enum set was not persisted correctly.", buyer.buysSaturdayToSunday());
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests an OptimisticLocking policy set on Buyer.
*/
public void testBuyerOptimisticLocking() {
// Cannot create parallel entity managers in the server.
if (isOnServer()) {
return;
}
EntityManager em1 = createEntityManager("fieldaccess");
EntityManager em2 = createEntityManager("fieldaccess");
em1.getTransaction().begin();
em2.getTransaction().begin();
RuntimeException caughtException = null;
try {
GoldBuyer buyer1 = em1.find(GoldBuyer.class, buyerId);
GoldBuyer buyer2 = em2.find(GoldBuyer.class, buyerId);
buyer1.setName("Geezer");
buyer2.setName("Guyzer");
// Uses field locking, so need to update version.
buyer1.setVersion(buyer1.getVersion() + 1);
buyer2.setVersion(buyer2.getVersion() + 1);
em1.getTransaction().commit();
em2.getTransaction().commit();
em1.close();
em2.close();
} catch (RuntimeException e) {
caughtException = e;
if (em1.getTransaction().isActive()){
em1.getTransaction().rollback();
}
if (em2.getTransaction().isActive()){
em2.getTransaction().rollback();
}
em1.close();
em2.close();
}
if (caughtException == null) {
fail("Optimistic lock exception was not thrown.");
} else if (!(caughtException.getCause() instanceof jakarta.persistence.OptimisticLockException)) {
// Re-throw exception to ensure stacktrace appears in test result.
throw caughtException;
}
}
/**
* Tests an ObjectTypeConverter on a direct to field mapping.
*/
public void testGiveFredAnObjectTypeConverterChange() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
EJBQueryImpl query = (EJBQueryImpl) em.createNamedQuery("findAllFieldAccessEmployeesByFirstName");
query.setParameter("firstname", "Fred");
Collection<Employee> employees = query.getResultCollection();
if (employees.isEmpty()) {
fail("No employees named Fred were found. Test requires at least one Fred to be created in the EmployeePopulator.");
} else {
Employee fred = employees.iterator().next();
fred.setFemale();
fred.setFirstName("Penelope");
penelopeId = fred.getId();
commitTransaction(em);
// Clear cache and clear the entity manager
clearCache("fieldaccess");
em.clear();
Employee penelope = em.find(Employee.class, penelopeId);
assertTrue("Fred's ObjectTypeConverter change to Penelope didn't occur.", penelope.isFemale());
}
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests a BasicCollection on an entity that uses a composite primary key.
*/
public void testUpdatePenelopesPhoneNumberStatus() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
Employee emp = em.find(Employee.class, penelopeId);
assertNotNull("The employee with id: [" + penelopeId + "] was not found.", emp);
for (PhoneNumber phoneNumber : emp.getPhoneNumbers()) {
phoneNumber.addStatus(PhoneNumber.PhoneStatus.ACTIVE);
phoneNumber.addStatus(PhoneNumber.PhoneStatus.ASSIGNED);
}
commitTransaction(em);
// Clear cache and clear the entity manager
clearCache("fieldaccess");
em.clear();
Employee emp2 = em.find(Employee.class, penelopeId);
for (PhoneNumber phone : emp2.getPhoneNumbers()) {
assertTrue("", phone.getStatus().contains(PhoneNumber.PhoneStatus.ACTIVE));
assertTrue("", phone.getStatus().contains(PhoneNumber.PhoneStatus.ASSIGNED));
}
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests a @PrivateOwned @OneToMany mapping.
*/
public void testRemoveJillWithPrivateOwnedPhoneNumbers() {
if (getServerSession("fieldaccess").getPlatform().isSymfoware()) {
getServerSession("fieldaccess").logMessage("Test testRemoveJillWithPrivateOwnedPhoneNumbers skipped for this platform, "
+ "The CascadeOnDelete doesn't work on a relation where CascadeType.Remove or CascadeType.All is specified on Symfoware Platform.");
return;
}
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
EJBQueryImpl query = (EJBQueryImpl) em.createNamedQuery("findAllFieldAccessEmployeesByFirstName");
query.setParameter("firstname", "Jill");
Collection<Employee> employees = query.getResultCollection();
if (employees.isEmpty()) {
fail("No employees named Jill were found. Test requires at least one Jill to be created in the EmployeePopulator.");
} else {
Employee jill = employees.iterator().next();
Collection<PhoneNumber> phoneNumbers = jill.getPhoneNumbers();
if (phoneNumbers.isEmpty()) {
fail("Jill does not have any phone numbers. Test requires that Jill have atleast one phone number created in the EmployeePopulator.");
}
// Re-assign her managed employees and remove from her list.
for (Employee employee : jill.getManagedEmployees()) {
employee.setManager(jill.getManager());
}
jill.getManagedEmployees().clear();
int jillId = jill.getId();
em.remove(jill);
commitTransaction(em);
assertNull("Jill herself was not removed.", em.find(Employee.class, jillId));
for (PhoneNumber phoneNumber : phoneNumbers) {
assertNull("Jill's phone numbers were not deleted.", em.find(PhoneNumber.class, phoneNumber.buildPK()));
}
}
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Creates some new equipment objects.
*/
public void testCreateNewEquipment() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
// Persist some equipment.
Equipment equip1 = new Equipment();
equip1.setDescription("Toaster");
em.persist(equip1);
Equipment equip2 = new Equipment();
equip1.setDescription("Bucket");
em.persist(equip2);
Equipment equip3 = new Equipment();
equip1.setDescription("Broom");
em.persist(equip3);
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests adding objects to a 1-M mapping that uses a map.
*/
public void testAddNewEquipmentToDepartment() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
EJBQueryImpl query = (EJBQueryImpl) em.createNamedQuery("findAllSQLEquipment");
Collection<Equipment> equipment = query.getResultCollection();
if (equipment.isEmpty()) {
fail("No Equipment was found. testCreateNewEquipment should have created new equipment and should have run before this test.");
} else {
Department department = new Department();
department.setName("Department with equipment");
for (Equipment e : equipment) {
department.addEquipment(e);
}
em.persist(department);
deptId = department.getId();
commitTransaction(em);
}
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests a @NamedStoredProcedureQuery.
*/
public void testNamedStoredProcedureQuery() {
if (!supportsStoredProcedures("fieldaccess")) {
return;
}
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
Address address1 = new Address();
address1.setCity("Ottawa");
address1.setPostalCode("K1G6P3");
address1.setProvince("ON");
address1.setStreet("123 Street");
address1.setCountry("Canada");
em.persist(address1);
commitTransaction(em);
// 260263 and 302316: clear the cache or we will end up with a false positive when comparing the entity to itself later
em.clear();
Query aQuery = em.createNamedQuery("SProcAddress").setParameter("ADDRESS_ID", address1.getId());
Address address2 = (Address) aQuery.getSingleResult();
assertNotNull("Address returned from stored procedure is null", address2);
assertFalse("Address returned is the same cached instance that was persisted - the cache must be disabled for this test", address1 == address2); // new
// Integer address handled differently than int
assertTrue("Address not found using stored procedure", address1.getId().intValue() == address2.getId().intValue());
assertTrue("Address.street data returned doesn't match persisted address.street", address1.getStreet().endsWith(address2.getStreet()));
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests a @NamedStoredProcedureQuery.
*/
public void testNamedStoredProcedureQueryInOut() {
if (!supportsStoredProcedures("fieldaccess")) {
return;
}
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
Address address1 = new Address();
address1.setCity("Ottawa");
address1.setPostalCode("K1G6P3");
address1.setProvince("ON");
address1.setStreet("123 Street");
address1.setCountry("Canada");
em.persist(address1);
commitTransaction(em);
// 260263 and 302316: clear the cache or we will end up with a false positive when comparing the entity to itself later
em.clear();
Query aQuery = em.createNamedQuery("SProcInOut").setParameter("ADDRESS_ID", address1.getId());
Address address2 = (Address) aQuery.getSingleResult();
assertNotNull("Address returned from stored procedure is null", address2);
assertFalse("Address returned is the same cached instance that was persisted - the cache must be disabled for this test", address1 == address2); // new
// Integer address handled differently than int
assertTrue("Address not found using stored procedure", address1.getId().intValue() == address2.getId().intValue());
assertTrue("Address.street data returned doesn't match persisted address.street", address1.getStreet().equals(address2.getStreet()));
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests a @NamedStoredProcedureQuery that returns raw data
* bug 254946
*/
public void testNamedStoredProcedureQueryWithRawData() {
if (!supportsStoredProcedures("fieldaccess")) {
return;
}
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
Address address1 = new Address();
address1.setCity("Ottawa");
address1.setPostalCode("K1G6P3");
address1.setProvince("ON");
address1.setStreet("123 Street");
address1.setCountry("Canada");
em.persist(address1);
commitTransaction(em);
// 260263: we do not need to clear the cache for non-entity returns
Query aQuery = em.createNamedQuery("SProcInOutReturningRawData").setParameter("ADDRESS_ID", address1.getId());
Object[] objectdata = (Object[])aQuery.getSingleResult();
assertTrue("Address data not found or returned using stored procedure", ((objectdata!=null) && (objectdata.length==2)) );
assertTrue("Address Id data returned doesn't match persisted address", (address1.getId() == ((Long)objectdata[0]).longValue()));
assertTrue("Address Street data returned doesn't match persisted address", ( address1.getStreet().equals(objectdata[1] )) );
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests a @PrivateOwned @OneToMany mapping.
*/
public void testRemoveDepartmentWithPrivateOwnedEquipment() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
Department department = em.find(Department.class, deptId);
if (department == null) {
fail("Department with id="+deptId+", was not found.");
} else {
Collection<Equipment> equipment = department.getEquipment().values();
if (equipment.isEmpty()){
fail("Department with id="+deptId+", did not have any equipment.");
} else {
em.remove(department);
commitTransaction(em);
assertNull("Department itself was not removed.", em.find(Department.class, deptId));
for (Equipment e : equipment) {
assertNull("New equipment was not deleted.", em.find(Equipment.class, e.getId()));
}
}
}
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* Tests trying to update a read only class.
*/
public void testUpdateReadOnlyEquipmentCode() {
EntityManager em = createEntityManager("fieldaccess");
beginTransaction(em);
try {
Query query = em.createNamedQuery("findSQLEquipmentCodeA");
EquipmentCode equipmentCode = (EquipmentCode) query.getSingleResult();
equipmentCode.setCode("Z");
commitTransaction(em);
// Nothing should have been written to the database. Query for
// EquipmentCode A again. If an exception is caught, then it was
// not found, therefore, updated on the db.
try {
query = em.createNamedQuery("findSQLEquipmentCodeA");
query.getSingleResult();
} catch (Exception e) {
fail("The read only EquipmentA was modified");
}
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
}
closeEntityManager(em);
}
/**
* This tests verifies two things:
* 1 - That a metadata named query is processed correctly when it uses a
* lock mode type.
* 2 - That a default persistence unit lock timeout value is correctly
* processed and utilized.
*/
public void testPessimisticLockingNamedQuery() {
ServerSession session = JUnitTestCase.getServerSession("fieldaccess");
// Cannot create parallel entity managers in the server. Skip on SQLServer since dead lock.
if (! isOnServer() && isSelectForUpateNoWaitSupported("fieldaccess") && !(session.getPlatform().isSQLServer())) {
EntityManager em = createEntityManager("fieldaccess");
Employee employee;
try {
beginTransaction(em);
employee = new Employee();
employee.setFirstName("Lucie");
employee.setLastName("Ogdensburgh");
em.persist(employee);
commitTransaction(em);
} catch (RuntimeException ex) {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
closeEntityManager(em);
throw ex;
}
Exception lockTimeoutException = null;
try {
beginTransaction(em);
// This query is configured as a pessimistic locking query.
employee = (Employee) em.createNamedQuery("findFieldAccessEmployeeByPK").setParameter("id", employee.getId()).getSingleResult();
EntityManager em2 = createEntityManager("fieldaccess");
try {
beginTransaction(em2);
Employee emp2 = em2.find(Employee.class, employee.getId(), LockModeType.PESSIMISTIC_READ);
} catch (PersistenceException ex) {
if (ex instanceof jakarta.persistence.LockTimeoutException) {
lockTimeoutException = ex;
} else {
throw ex;
}
} finally {
closeEntityManagerAndTransaction(em2);
}
commitTransaction(em);
} catch (RuntimeException ex) {
if (isTransactionActive(em)) {
rollbackTransaction(em);
}
throw ex;
} finally {
closeEntityManager(em);
}
assertFalse("A lock timeout exception was not thrown (likely because the persistence unit lock timeout default property was not processed).", lockTimeoutException == null);
}
}
}