blob: c75a82e3c3b77af91822dbb5d7d73dae31d424f7 [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
// 09/23/2008-1.1 Guy Pelletier
// - 241651: JPA 2.0 Access Type support
// 03/08/2010-2.1 Guy Pelletier
// - 303632: Add attribute-type for mapping attributes to EclipseLink-ORM
// 03/29/2010-2.1 Guy Pelletier
// - 267217: Add Named Access Type to EclipseLink-ORM
// 04/09/2010-2.1 Guy Pelletier
// - 307050: Add defaults for access methods of a VIRTUAL access type
// 07/05/2010-2.1.1 Guy Pelletier
// - 317708: Exception thrown when using LAZY fetch on VIRTUAL mapping
// 11/17/2010-2.2 Guy Pelletier
// - 329008: Support dynamic context creation without persistence.xml
// 08/20/2012-2.4 Guy Pelletier
// - 381079: EclipseLink dynamic entity does not support embedded-id
package org.eclipse.persistence.testing.tests.jpa.xml.advanced;
import java.lang.reflect.Method;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jakarta.persistence.EntityNotFoundException;
import jakarta.persistence.Query;
import jakarta.persistence.EntityManager;
import org.junit.Assert;
import junit.framework.Test;
import junit.framework.TestSuite;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.descriptors.RelationalDescriptor;
import org.eclipse.persistence.dynamic.DynamicClassLoader;
import org.eclipse.persistence.dynamic.DynamicEntity;
import org.eclipse.persistence.dynamic.DynamicType;
import org.eclipse.persistence.jpa.JpaEntityManager;
import org.eclipse.persistence.jpa.dynamic.JPADynamicHelper;
import org.eclipse.persistence.mappings.DatabaseMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.queries.DoesExistQuery;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.framework.TestCase;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper;
import org.eclipse.persistence.testing.models.jpa.xml.advanced.dynamic.DynamicTableCreator;
import org.eclipse.persistence.testing.models.jpa.xml.advanced.dynamic.DynamicWalkerPK;
import org.eclipse.persistence.testing.models.jpa.xml.advanced.dynamic.MyDynamicEntity;
import org.eclipse.persistence.testing.models.jpa.xml.advanced.dynamic.AdvancedDynamicTableCreator;
import org.eclipse.persistence.tools.schemaframework.SchemaManager;
import org.eclipse.persistence.tools.schemaframework.StoredProcedureDefinition;
/**
* JUnit test case(s) for testing extended jpa dynamic persistence.
*/
public class EntityMappingsDynamicAdvancedJUnitTestCase extends JUnitTestCase {
public enum MaterialType { Wood, Plastic, Composite, Steel }
private static final String AMEX = "Amex";
private static final String DINERS = "DinersClub";
private static final String MASTERCARD = "Mastercard";
private static final String VISA = "Visa";
private static final String ROYAL_BANK = "RoyalBank";
private static final String CANADIAN_IMPERIAL = "CanadianImperial";
private static final String SCOTIABANK = "Scotiabank";
private static final String TORONTO_DOMINION = "TorontoDominion";
private static Integer employeeId;
private static long visa = 1234567890;
private static long amex = 1987654321;
private static long diners = 1192837465;
private static long mastercard = 1647382910;
private static long rbc = 4783;
private static long scotia = 8732;
private static long td = 839362;
private static long cibc = 948274;
public EntityMappingsDynamicAdvancedJUnitTestCase(String name) {
super(name);
}
/**
* Build stored procedure used in tests.
*/
protected StoredProcedureDefinition buildOracleStoredProcedureReadFromAddress(DatabaseSession session) {
StoredProcedureDefinition proc = new StoredProcedureDefinition();
proc.setName("SProc_Read_DynamicAddress");
proc.addInOutputArgument("address_id_v", Integer.class);
proc.addOutputArgument("street_v", String.class);
proc.addOutputArgument("city_v", String.class);
proc.addOutputArgument("country_v", String.class);
proc.addOutputArgument("province_v", String.class);
proc.addOutputArgument("p_code_v", String.class);
/**
* SQLServer 2008 requires extra prefix and delimiting chars in select statements in stored procedures
*/
String statement = null;
if(session.getPlatform().isSQLServer() || session.getPlatform().isSybase()) {
// 260263: SQLServer 2005/2008 requires parameter matching in the select clause for stored procedures
statement = "SELECT @street_v=STREET, @city_v=CITY, @country_v=COUNTRY, @province_v=PROVINCE, @p_code_v=P_CODE FROM DYNAMIC_ADDRESS WHERE (ADDRESS_ID = @address_id_v)";
} else {
statement = "SELECT STREET, CITY, COUNTRY, PROVINCE, P_CODE INTO street_v, city_v, country_v, province_v, p_code_v FROM DYNAMIC_ADDRESS WHERE (ADDRESS_ID = address_id_v)";
}
proc.addStatement(statement);
return proc;
}
/**
* Build stored procedure used in tests.
*/
protected StoredProcedureDefinition buildOracleStoredProcedureReadInOut(DatabaseSession session) {
StoredProcedureDefinition proc = new StoredProcedureDefinition();
proc.setName("SProc_Read_DynamicInOut");
proc.addInOutputArgument("address_id_v", Long.class);
proc.addOutputArgument("street_v", String.class);
/**
* SQLServer 2008 requires extra prefix and delimiting chars in select statements in stored procedures
*/
String statement = null;
if(session.getPlatform().isSQLServer() || session.getPlatform().isSybase()) {
// 260263: SQLServer 2005/2008 requires parameter matching in the select clause for stored procedures
statement = "SELECT @address_id_v=ADDRESS_ID, @street_v=STREET from DYNAMIC_ADDRESS where (ADDRESS_ID = @address_id_v)";
} else {
statement = "SELECT ADDRESS_ID, STREET into address_id_v, street_v from DYNAMIC_ADDRESS where (ADDRESS_ID = address_id_v)";
}
proc.addStatement(statement);
return proc;
}
/**
* Clear the cache of the dynamic persistence unit.
*/
protected void clearDynamicPUCache() {
clearCache("extended-dynamic-advanced");
}
/**
* Create our dynamic persistence unit entity manager.
*/
protected EntityManager createDynamicPUEntityManager() {
return createEntityManager("extended-dynamic-advanced", getDynamicProperties());
}
/**
* Create a dynamic entity manager from no persistence.xml file.
*/
protected EntityManager createDynamicEntityManager(String persistenceUnitName, List<ClassDescriptor> descriptors) {
return createEntityManager(persistenceUnitName, getDynamicProperties(), descriptors);
}
/**
* Return the class descriptor for the given dynamic entity alias.
*/
protected ClassDescriptor getDescriptor(String alias) {
ClassDescriptor descriptor = getDynamicPUServerSession().getDescriptorForAlias(alias);
assertFalse("Descriptor for alias: " + alias + ", was not found.", descriptor == null);
return descriptor;
}
/**
* Return the properties needed for dynamic persistence.
*/
protected Map getDynamicProperties() {
Map properties = JUnitTestCaseHelper.getDatabaseProperties();
properties.put(PersistenceUnitProperties.CLASSLOADER, new DynamicClassLoader(Thread.currentThread().getContextClassLoader()));
return properties;
}
/**
* Return the dynamic persistence unit server session.
*/
protected ServerSession getDynamicPUServerSession() {
return getServerSession("extended-dynamic-advanced", getDynamicProperties());
}
/**
* Verifies that the change tracking metadata is correctly processed. In
* this case a DEFERRED setting is overridden by a hard force to attribute
* change tracking for VIRTUAL classes.
*/
public void testAddressChangeTrackingPolicy() {
assertTrue("Address descriptor has incorrect object change policy", getDescriptor("DynamicAddress").getObjectChangePolicyInternal().isAttributeChangeTrackingPolicy());
}
/**
* Return the dynamic test suite.
*/
public static Test suite() {
// This test suite should only be called when we are using the
// extended-dynamic-advanced test suite.
TestSuite suite = new TestSuite("Advanced Dynamic Model");
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testSetup"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testExistenceCheckingSetting"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testReadOnlyClassSetting"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testEmployeeChangeTrackingPolicy"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testAddressChangeTrackingPolicy"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testProjectChangeTrackingPolicy"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testCreateEmployee"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testUpdateEmployee"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testDynamicShovel"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testRefreshNotManagedEmployee"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testRefreshRemovedEmployee"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testNamedNativeQueryOnAddress"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testNamedQueryOnEmployee"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testNamedStoredProcedureQuery"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testNamedStoredProcedureQueryInOut"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testDeleteEmployee"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testDynamicWithNoPersistenceXML"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testDynamicEmbeddedId"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testDynamicCompositeId"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testEmployeeWeaving"));
suite.addTest(new EntityMappingsDynamicAdvancedJUnitTestCase("testAddressWeaving"));
return suite;
}
/**
* Test create dynamic employee
*/
public void testCreateEmployee() {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
try {
beginTransaction(em);
DynamicEntity employee = helper.newDynamicEntity("DynamicEmployee");
employee.set("firstName", "Boy");
employee.set("lastName", "Pelletier");
employee.set("salary", 20000);
Map<String, Long> creditCards = new HashMap<String, Long>();
creditCards.put(VISA, visa);
creditCards.put(AMEX, amex);
creditCards.put(DINERS, diners);
creditCards.put(MASTERCARD, mastercard);
employee.set("creditCards", creditCards);
Map<String, Long> creditLines = new HashMap<String, Long>();
creditLines.put(ROYAL_BANK, rbc);
creditLines.put(SCOTIABANK, scotia);
creditLines.put(TORONTO_DOMINION, td);
creditLines.put(CANADIAN_IMPERIAL, cibc);
employee.set("creditLines", creditLines);
Collection<String> responsibilities = new ArrayList<String>();
responsibilities.add("A very important responsibility");
employee.set("responsibilities", responsibilities);
DynamicEntity address = helper.newDynamicEntity("DynamicAddress");
address.set("city", "Nepean");
address.set("country", "Canada");
address.set("postalCode", "K2J 6T3");
// One it goes through the custom converter this should be set to Ontario.
address.set("province", "oNtArIo");
address.set("street", "321 Crestway");
employee.set("address", address);
DynamicEntity employmentPeriod = helper.newDynamicEntity("EmploymentPeriod");
employmentPeriod.set("startDate", new Date(System.currentTimeMillis()-1000000));
employmentPeriod.set("endDate", new Date(System.currentTimeMillis()+1000000));
employee.set("period", employmentPeriod);
ArrayList<DynamicEntity> projects = new ArrayList<DynamicEntity>();
DynamicEntity project = helper.newDynamicEntity("DynamicProject");
project.set("description", "A Project");
project.set("name", "Project");
projects.add(project);
DynamicEntity largeProject = helper.newDynamicEntity("DynamicLargeProject");
largeProject.set("description", "A LargeProject");
largeProject.set("name", "LargeProject");
largeProject.set("budget", 3654563.0);
projects.add(largeProject);
employee.set("projects", projects);
em.persist(employee);
employeeId = employee.get("id");
commitTransaction(em);
clearDynamicPUCache();
em.clear();
// Re-read the employee and verify the data.
DynamicEntity emp = em.find(helper.getType("DynamicEmployee").getJavaClass(), employeeId);
//assertTrue("Employee didn't match after create", getDynamicPUServerSession().compareObjects(emp, employee));
assertNotNull("The employee was not found", emp);
// Compare all the data we persisted.
DynamicEntity addr = emp.get("address");
assertTrue("The address province value was not converted", addr.get("province").equals("Ontario"));
Map<String, Long> ccs = emp.get("creditCards");
assertTrue("Visa card did not persist correctly.", ccs.containsKey(VISA));
assertTrue("Visa card value did not persist correctly.", ccs.get(VISA).equals(visa));
assertTrue("Amex card did not persist correctly.", ccs.containsKey(AMEX));
assertTrue("Amex card value did not persist correctly.", ccs.get(AMEX).equals(amex));
assertTrue("Diners Club card did not persist correctly.", ccs.containsKey(DINERS));
assertTrue("Diners Club card value did not persist correctly.", ccs.get(DINERS).equals(diners));
assertTrue("Mastercard card did not persist correctly.", ccs.containsKey(MASTERCARD));
assertTrue("Mastercard card value did not persist correctly.", ccs.get(MASTERCARD).equals(mastercard));
Map<String, Long> cls = emp.get("creditLines");
assertTrue("RBC credit line did not persist correctly.", cls.containsKey(ROYAL_BANK));
assertTrue("RBC credit line value did not persist correctly.", cls.get(ROYAL_BANK).equals(rbc));
assertTrue("Scotia credit line did not persist correctly.", cls.containsKey(SCOTIABANK));
assertTrue("Scotia credit line value did not persist correctly.", cls.get(SCOTIABANK).equals(scotia));
assertTrue("TD credit line did not persist correctly.", cls.containsKey(TORONTO_DOMINION));
assertTrue("TD credit line value did not persist correctly.", cls.get(TORONTO_DOMINION).equals(td));
assertTrue("CIBC credit line did not persist correctly.", cls.containsKey(CANADIAN_IMPERIAL));
assertTrue("CIBC credit line value did not persist correctly.", cls.get(CANADIAN_IMPERIAL).equals(cibc));
boolean found = false;
for (String responsibility : (Collection<String>) emp.get("responsibilities")) {
if (responsibility.equals("A very important responsibility")) {
found = true;
break;
}
}
assertTrue("The new responsibility was not added.", found);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
/**
* Test delete dynamic employee
*/
public void testDeleteEmployee() {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
try {
beginTransaction(em);
em.remove(em.find(helper.getType("DynamicEmployee").getJavaClass(), employeeId));
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
/**
* Verifies that attribute-types and name access are correctly processed
* and used.
*/
public void testDynamicShovel() {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
try {
beginTransaction(em);
// Cost
DynamicEntity shovel = helper.newDynamicEntity("DynamicShovel");
shovel.set("cost", 9.99);
// Sections
DynamicEntity shovelSections = helper.newDynamicEntity("ShovelSections");
shovelSections.set("handle", MaterialType.Plastic.name());
shovelSections.set("shaft", MaterialType.Wood.name());
shovelSections.set("scoop", MaterialType.Plastic.name());
shovel.set("sections", shovelSections);
// Owner
DynamicEntity shovelOwner = helper.newDynamicEntity("DynamicShovelOwner");
shovelOwner.set("name", "Mr. Shovel");
shovel.set("owner", shovelOwner);
// Operators
DynamicEntity shovelDigger1 = helper.newDynamicEntity("DynamicShovelDigger");
shovelDigger1.set("name", "Digging Plebe 1");
shovelDigger1.set("shovel", shovel);
DynamicEntity shovelDigger2 = helper.newDynamicEntity("DynamicShovelDigger");
shovelDigger2.set("name", "Digging Plebe 2");
shovelDigger2.set("shovel", shovel);
List<DynamicEntity> operators = new ArrayList<DynamicEntity>();
operators.add(shovelDigger1);
operators.add(shovelDigger2);
shovel.set("operators", operators);
// Projects
DynamicEntity shovelProject = helper.newDynamicEntity("DynamicShovelProject");
shovelProject.set("description", "One lousy shovelling project");
List<DynamicEntity> shovels = new ArrayList<DynamicEntity>();
shovels.add(shovel);
shovelProject.set("shovels", shovels);
List<DynamicEntity> projects = new ArrayList<DynamicEntity>();
projects.add(shovelProject);
shovel.set("projects", projects);
em.persist(shovel);
// Grab id's for ease of lookup.
Object shovelId = shovel.get("id");
Object shovelOwnerId = shovelOwner.get("id");
Object shovelDigger1Id = shovelDigger1.get("id");
Object shovelDigger2Id = shovelDigger2.get("id");
Object shovelProjectId = shovelProject.get("id");
commitTransaction(em);
clearDynamicPUCache();
em.clear();
DynamicEntity refreshedShovel = em.find(helper.getType("DynamicShovel").getJavaClass(), shovelId);
assertTrue("Shovel didn't match after write/read", getDynamicPUServerSession().compareObjects(shovel, refreshedShovel));
// Do an update
beginTransaction(em);
em.merge(refreshedShovel);
refreshedShovel.set("cost", 7.99);
commitTransaction(em);
clearDynamicPUCache();
em.clear();
DynamicEntity refreshedUpdatedShovel = em.find(helper.getType("DynamicShovel").getJavaClass(), shovelId);
assertTrue("Shovel didn't match after update", getDynamicPUServerSession().compareObjects(refreshedShovel, refreshedUpdatedShovel));
// Now delete it
beginTransaction(em);
em.merge(refreshedUpdatedShovel);
em.remove(refreshedUpdatedShovel);
commitTransaction(em);
// Check what's left
assertNull("Shovel wasn't removed", em.find(helper.getType("DynamicShovel").getJavaClass(), shovelId));
assertNull("Shovel owner wasn't removed", em.find(helper.getType("DynamicShovelOwner").getJavaClass(), shovelOwnerId));
assertNull("Shovel digger 1 wasn't removed", em.find(helper.getType("DynamicShovelDigger").getJavaClass(), shovelDigger1Id));
assertNull("Shovel digger 2 wasn't removed", em.find(helper.getType("DynamicShovelDigger").getJavaClass(), shovelDigger2Id));
assertNotNull("Shovel project was removed", em.find(helper.getType("DynamicShovelProject").getJavaClass(), shovelProjectId));
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
/**
* Test a dynamic persistence unit using no persistence.xml.
*/
public void testDynamicWithNoPersistenceXML() {
// This is a Java SE feature only.
if (! isOnServer()) {
List<ClassDescriptor> descriptors = new ArrayList<ClassDescriptor>();
RelationalDescriptor descriptor = new RelationalDescriptor();
descriptor.setJavaClassName("org.eclipse.persistence.testing.models.jpa.xml.advanced.dynamic.MyDynamicEntity");
descriptor.setAlias("MyDynamicEntity");
descriptor.setTableName("JPA_DYNAMIC_ENTITY");
descriptor.addPrimaryKeyFieldName("ID");
descriptor.setSequenceNumberFieldName("ID");
descriptor.setSequenceNumberName("DYNAMIC_SEQ");
descriptor.addDirectMapping("id", "ID");
descriptor.addDirectMapping("firstName", "F_NAME");
descriptor.addDirectMapping("lastName", "L_NAME");
descriptors.add(descriptor);
EntityManager em = createDynamicEntityManager("dynamic-test", descriptors);
new DynamicTableCreator().replaceTables(((JpaEntityManager) em).getServerSession());
try {
beginTransaction(em);
em.persist(new MyDynamicEntity("Doug", "Clarke"));
em.persist(new MyDynamicEntity("Peter", "Krogh"));
commitTransaction(em);
clearCache("dynamic-test");
em.clear();
List<MyDynamicEntity> results = em.createQuery("SELECT d FROM MyDynamicEntity d").getResultList();
assertFalse("No dynamic entities were returned from the query", results.isEmpty());
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
}
/**
* Verifies that existence-checking metadata is correctly processed.
*/
public void testExistenceCheckingSetting() {
assertTrue("Employee existence checking was incorrect", getDescriptor("DynamicEmployee").getQueryManager().getDoesExistQuery().getExistencePolicy() == DoesExistQuery.CheckDatabase);
assertTrue("Project existence checking was incorrect", getDescriptor("DynamicProject").getQueryManager().getDoesExistQuery().getExistencePolicy() == DoesExistQuery.CheckCache);
assertTrue("SmallProject existence checking was incorrect", getDescriptor("DynamicSmallProject").getQueryManager().getDoesExistQuery().getExistencePolicy() == DoesExistQuery.AssumeExistence);
assertTrue("LargeProject existence checking was incorrect", getDescriptor("DynamicLargeProject").getQueryManager().getDoesExistQuery().getExistencePolicy() == DoesExistQuery.AssumeNonExistence);
}
/**
* Employee has EAGER collection mappings, so change tracking is not possible.
*/
public void testEmployeeChangeTrackingPolicy() {
assertFalse("Employee descriptor has incorrect object change policy", getDescriptor("DynamicEmployee").getObjectChangePolicy().isAttributeChangeTrackingPolicy());
}
/**
* Query test
*/
public void testNamedNativeQueryOnAddress() {
EntityManager em = createDynamicPUEntityManager();
List<DynamicEntity> addresses = em.createNamedQuery("findAllDynamicAddressesByPostalCode", DynamicEntity.class).setParameter("postalCode", "K2J 6T3").getResultList();
assertFalse("No addresses were returned, expecting 1", addresses.isEmpty());
assertTrue("Incorrect number of addresses returned, expected 1, got: " + addresses.size(), addresses.size() == 1);
closeEntityManager(em);
}
/**
* Query test
*/
public void testNamedQueryOnEmployee() {
EntityManager em = createDynamicPUEntityManager();
DynamicEntity employee = em.createNamedQuery("findAllDynamicEmployeesByFirstName", DynamicEntity.class).setParameter("firstName", "Boy").getSingleResult();
assertTrue("Error executing named query 'findAllDynamicEmployeesByFirstName'", employee != null);
closeEntityManager(em);
}
/**
* Tests a named-stored-procedure-query setting
*/
public void testNamedStoredProcedureQuery() {
if (supportsStoredProcedures("extended-dynamic-advanced")) {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
try {
beginTransaction(em);
DynamicEntity address1 = helper.newDynamicEntity("DynamicAddress");
address1.set("city", "Ottawa");
address1.set("country", "Canada");
address1.set("postalCode", "K1G 6P3");
address1.set("province", "ON");
address1.set("street", "123 Street");
em.persist(address1);
commitTransaction(em);
clearDynamicPUCache();
em.clear();
Query aQuery = em.createNamedQuery("SProcDynamicAddress").setParameter("ADDRESS_ID", address1.get("id"));
DynamicEntity address2 = (DynamicEntity) 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);
assertTrue("Address not found using stored procedure", address1.get("id").equals(address2.get("id")));
assertTrue("Address.street data returned doesn't match persisted address.street", address1.get("street").equals(address2.get("street")));
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
} finally {
closeEntityManager(em);
}
}
}
/**
* Tests a named-stored-procedure-query setting
*/
public void testNamedStoredProcedureQueryInOut() {
if (supportsStoredProcedures("extended-dynamic-advanced")) {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
try {
beginTransaction(em);
DynamicEntity address1 = helper.newDynamicEntity("DynamicAddress");
address1.set("city", "Ottawa");
address1.set("postalCode", "K1G6P3");
address1.set("province", "ON");
address1.set("street", "123 Street");
address1.set("country", "Canada");
em.persist(address1);
commitTransaction(em);
em.clear();
Query aQuery = em.createNamedQuery("SProcDynamicInOut").setParameter("ADDRESS_ID", address1.get("id"));
DynamicEntity address2 = (DynamicEntity) 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
assertTrue("Address not found using stored procedure", address1.get("id").equals(address2.get("id")));
assertTrue("Address.street data returned doesn't match persisted address.street", address1.get("street").equals(address2.get("street")));
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
// Re-throw exception to ensure stacktrace appears in test result.
throw e;
} finally {
closeEntityManager(em);
}
}
}
/**
* Verifies that the change tracking metadata is correctly processed.
*/
public void testProjectChangeTrackingPolicy() {
assertTrue("Project descriptor has incorrect object change policy", getDescriptor("DynamicProject").getObjectChangePolicy().isObjectChangeTrackingPolicy());
}
/**
* Verifies that the read-only metadata is correctly processed.
*/
public void testReadOnlyClassSetting() {
assertTrue("ReadOnlyClass descriptor is not set to read only.", getDescriptor("DynamicReadOnlyClass").shouldBeReadOnly());
}
/**
* Test
*/
public void testRefreshNotManagedEmployee() {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
try {
beginTransaction(em);
DynamicEntity employee = helper.newDynamicEntity("DynamicEmployee");
employee.set("firstName", "NotManaged");
em.refresh(employee);
fail("entityManager.refresh(notManagedObject) didn't throw exception");
} catch (IllegalArgumentException illegalArgumentException) {
// expected behavior
} catch (RuntimeException e ) {
throw e;
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
public void testRefreshRemovedEmployee() {
// find an existing or create a new Employee
String firstName = "testRefreshRemovedEmployee";
DynamicEntity emp;
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
List<DynamicEntity> result = em.createQuery("SELECT OBJECT(e) FROM DynamicEmployee e WHERE e.firstName = '"+firstName+"'").getResultList();
if (! result.isEmpty()) {
emp = result.get(0);
} else {
emp = helper.newDynamicEntity("DynamicEmployee");
emp.set("firstName", firstName);
try {
// persist the Employee
beginTransaction(em);
em.persist(emp);
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
throw e;
}
}
try {
beginTransaction(em);
emp = em.find(helper.getType("DynamicEmployee").getJavaClass(), emp.get("id"));
if (getDynamicPUServerSession().getPlatform().isSymfoware()) {
// Symfoware does not support deleteall with multiple table
em.createNativeQuery("DELETE FROM DYNAMIC_EMPLOYEE WHERE F_NAME = '"+firstName+"'").executeUpdate();
} else {
// delete the Employee from the db
em.createQuery("DELETE FROM DynamicEmployee e WHERE e.firstName = '"+firstName+"'").executeUpdate();
}
// refresh the Employee - should fail with EntityNotFoundException
em.refresh(emp);
fail("entityManager.refresh(removedObject) didn't throw exception");
} catch (EntityNotFoundException entityNotFoundException) {
// expected behavior
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
/**
* The setup is done as a test, both to record its failure, and to allow
* execution in the server.
*/
public void testSetup() {
ServerSession session = getDynamicPUServerSession();
new AdvancedDynamicTableCreator().replaceTables(session);
if (TestCase.supportsStoredProcedures(session)) {
SchemaManager schema = new SchemaManager((DatabaseSession) session);
schema.replaceObject(buildOracleStoredProcedureReadFromAddress(session));
schema.replaceObject(buildOracleStoredProcedureReadInOut(session));
}
}
/**
* Test update dynamic employee
*/
public void testUpdateEmployee() {
EntityManager em = createDynamicPUEntityManager();
beginTransaction(em);
Integer version = 0;
try {
DynamicEntity employee = em.createNamedQuery("findDynamicEmployeeById", DynamicEntity.class).setParameter("id", employeeId).getSingleResult();
assertNotNull("The employee was not found", employee);
version = employee.get("version");
employee.set("salary", 50000);
em.merge(employee);
commitTransaction(em);
// Clear cache and clear the entity manager
clearDynamicPUCache();
em.clear();
List<DynamicEntity> emps = em.createNamedQuery("findDynamicEmployeeById", DynamicEntity.class).setParameter("id", employeeId).getResultList();
DynamicEntity emp = emps.get(0);
assertNotNull("The employee was not found", emp);
assertTrue("Error updating Employee", emp.get("salary").equals(50000));
assertTrue("Version field not updated", emp.get("version").equals(version + 1));
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
/**
* Test create and read of dynamic entity using an embedded id.
*/
public void testDynamicEmbeddedId() {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
try {
beginTransaction(em);
DynamicEntity runner = helper.newDynamicEntity("DynamicRunner");
runner.set("name", "Ryan Hill");
DynamicEntity runnerPK = helper.newDynamicEntity("DynamicRunnerPK");
runnerPK.set("bib", 1);
runnerPK.set("worldRank", 13);
runner.set("id", runnerPK);
em.persist(runner);
commitTransaction(em);
clearDynamicPUCache();
em.clear();
// Re-read the runner and verify the data.
DynamicEntity r = em.find(helper.getType("DynamicRunner").getJavaClass(), runnerPK);
assertTrue("Runner didn't match after create", getDynamicPUServerSession().compareObjects(r, runner));
assertNotNull("The runner was not found", r);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
/**
* Test create and read of dynamic entity using an embedded id.
*/
public void testDynamicCompositeId() {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
try {
beginTransaction(em);
DynamicEntity walker = helper.newDynamicEntity("DynamicWalker");
walker.set("name", "Sam");
walker.set("style", "Speed");
em.persist(walker);
commitTransaction(em);
clearDynamicPUCache();
em.clear();
// Re-read the walker and see if an exception occurs.
DynamicWalkerPK pk = new DynamicWalkerPK();
pk.setId(walker.get("id"));
pk.setStyle(walker.get("style"));
DynamicEntity w = em.find(helper.getType("DynamicWalker").getJavaClass(), pk);
assertNotNull("The walker was not found", w);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
fail("Error occurred reading the walker with composite id" + e);
//throw e;
} finally {
closeEntityManager(em);
}
}
public void testEmployeeWeaving() throws Exception {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
DynamicType type = helper.getType("DynamicEmployee");
Assert.assertNotNull(type);
Assert.assertTrue(DynamicEntity.class.isAssignableFrom(type.getJavaClass()));
assertAccessors(type);
}
public void testAddressWeaving() throws Exception {
EntityManager em = createDynamicPUEntityManager();
JPADynamicHelper helper = new JPADynamicHelper(em);
DynamicType type = helper.getType("DynamicAddress");
Assert.assertNotNull(type);
Assert.assertTrue(DynamicEntity.class.isAssignableFrom(type.getJavaClass()));
assertAccessors(type);
}
/**
* Assert that all mappings have get/set methods matching mappings and their
* accessor classification types.
*/
private void assertAccessors(DynamicType type) throws Exception {
for (DatabaseMapping mapping : type.getDescriptor().getMappings()) {
String propertyName = propertyName(mapping.getAttributeName());
@SuppressWarnings("unchecked")
Method method = mapping.getDescriptor().getJavaClass().getDeclaredMethod("get" + propertyName, new Class[0]);
Class<?> expectedReturnType = mapping.getAttributeClassification();
if (mapping.isCollectionMapping()) {
expectedReturnType = mapping.getContainerPolicy().getContainerClass();
}
if (expectedReturnType == null && mapping.isForeignReferenceMapping()) {
ForeignReferenceMapping frMapping = (ForeignReferenceMapping) mapping;
expectedReturnType = frMapping.getReferenceDescriptor().getJavaClass();
}
Assert.assertNotNull("No classification for: " + mapping, expectedReturnType);
if (!expectedReturnType.isPrimitive()) {
Assert.assertTrue("Incorrect get" + propertyName + " return type: " + method.getReturnType(), method.getReturnType().isAssignableFrom(expectedReturnType));
}
}
}
/**
* Convert attribute name into property name to be used in get/set method
* names by upper casing first letter.
*/
private String propertyName(String attributeName) {
char string[] = attributeName.toCharArray();
string[0] = Character.toUpperCase(string[0]);
return new String(string);
}
}