blob: a97cb6f84638d153cd8350efdb0856ebf33f3b3f [file] [log] [blame]
/*
* Copyright (c) 2011, 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:
// 03/23/2011-2.3 Guy Pelletier
// - 337323: Multi-tenant with shared schema support (part 1)
// 04/01/2011-2.3 Guy Pelletier
// - 337323: Multi-tenant with shared schema support (part 2)
// 04/21/2011-2.3 Guy Pelletier
// - 337323: Multi-tenant with shared schema support (part 5)
// 05/24/2011-2.3 Guy Pelletier
// - 345962: Join fetch query when using tenant discriminator column fails.
// 06/1/2011-2.3 Guy Pelletier
// - 337323: Multi-tenant with shared schema support (part 9)
// 06/30/2011-2.3.1 Guy Pelletier
// - 341940: Add disable/enable allowing native queries
// 09/09/2011-2.3.1 Guy Pelletier
// - 356197: Add new VPD type to MultitenantType
// 11/10/2011-2.4 Guy Pelletier
// - 357474: Address primaryKey option from tenant discriminator column
// 11/15/2011-2.3.2 Guy Pelletier
// - 363820: Issue with clone method from VPDMultitenantPolicy
// 14/05/2012-2.4 Guy Pelletier
// - 376603: Provide for table per tenant support for multitenant applications
// 22/05/2012-2.4 Guy Pelletier
// - 380008: Multitenant persistence units with a dedicated emf should force tenant property specification up front.
// 01/06/2011-2.3 Guy Pelletier
// - 371453: JPA Multi-Tenancy in Bidirectional OneToOne Relation throws ArrayIndexOutOfBoundsException
// 08/11/2012-2.5 Guy Pelletier
// - 393867: Named queries do not work when using EM level Table Per Tenant Multitenancy.
// 20/11/2012-2.5 Guy Pelletier
// - 394524: Invalid query key [...] in expression
package org.eclipse.persistence.testing.tests.jpa.advanced.multitenant;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.NamedQuery;
import jakarta.persistence.Persistence;
import jakarta.persistence.Query;
import jakarta.persistence.TypedQuery;
import junit.framework.*;
import org.eclipse.persistence.queries.SQLCall;
import org.eclipse.persistence.sessions.DatabaseSession;
import org.eclipse.persistence.sessions.Session;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCaseHelper;
import org.eclipse.persistence.config.EntityManagerProperties;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.config.QueryHints;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.Helper;
import org.eclipse.persistence.internal.jpa.EJBQueryImpl;
import org.eclipse.persistence.internal.sessions.AbstractSession;
import org.eclipse.persistence.jpa.JpaEntityManager;
import org.eclipse.persistence.jpa.JpaHelper;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Address;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.AdvancedMultiTenantTableCreator;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Boss;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Candidate;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Capo;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Card;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Contract;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.MafiaFamily;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Mafioso;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Mason;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Party;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.PhoneNumber;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Reward;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Riding;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Soldier;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.SubCapo;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.SubTask;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Supporter;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.SupporterInfo;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.SupporterInfoSub;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Task;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Trowel;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Underboss;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Card;
import org.eclipse.persistence.testing.models.jpa.advanced.multitenant.Envelope;
public class AdvancedMultiTenantJunitTest extends JUnitTestCase {
public String MULTI_TENANT_VPD_PU;
public String MULTI_TENANT_PU;
public String MULTI_TENANT_PU_123;
public String MULTI_TENANT_TABLE_PER_TENANT_PU;
public String MULTI_TENANT_TABLE_PER_TENANT_C_PU;
public static long candidateAId;
public static long supporter1Id;
public static long supporter2Id;
public static int ridingId;
public static int partyId;
public static int masonId;
public static int family707;
public static int family007;
public static int family123;
public static int capo123Id;
public static int soldier123Id;
public static List<Integer> family707Mafiosos = new ArrayList<Integer>();
public static List<Integer> family707Contracts = new ArrayList<Integer>();
public static List<Integer> family007Mafiosos = new ArrayList<Integer>();
public static List<Integer> family007Contracts = new ArrayList<Integer>();
public static List<Integer> family123Mafiosos = new ArrayList<Integer>();
public static List<Integer> family123Contracts = new ArrayList<Integer>();
public AdvancedMultiTenantJunitTest() {
super();
}
public AdvancedMultiTenantJunitTest(String name) {
super(name);
}
@Override
public void setUp() {}
public static Test suite() {
TestSuite suite = new TestSuite();
suite.setName("AdvancedMultiTenantJunitTest");
suite.addTest(new AdvancedMultiTenantJunitTest("testSetup"));
suite.addTest(new AdvancedMultiTenantJunitTest("testCreateMafiaFamily707"));
suite.addTest(new AdvancedMultiTenantJunitTest("testCreateMafiaFamily007"));
suite.addTest(new AdvancedMultiTenantJunitTest("testCreateEMF123WithoutAllTenantPropertiesSet"));
suite.addTest(new AdvancedMultiTenantJunitTest("testCreateMafiaFamily123"));
suite.addTest(new AdvancedMultiTenantJunitTest("testValidateMafiaFamily707"));
suite.addTest(new AdvancedMultiTenantJunitTest("testValidateMafiaFamily007"));
suite.addTest(new AdvancedMultiTenantJunitTest("testValidateMafiaFamily707and007WithSameEM"));
suite.addTest(new AdvancedMultiTenantJunitTest("testValidateMafiaFamily123"));
suite.addTest(new AdvancedMultiTenantJunitTest("testComplexMultitenantQueries"));
suite.addTest(new AdvancedMultiTenantJunitTest("testVPDEMPerTenant"));
suite.addTest(new AdvancedMultiTenantJunitTest("testMultitenantOneToOneReadObjectRead"));
suite.addTest(new AdvancedMultiTenantJunitTest("testMultitenantPrimaryKeyWithIdClass"));
suite.addTest(new AdvancedMultiTenantJunitTest("testTablePerTenantA"));
suite.addTest(new AdvancedMultiTenantJunitTest("testTablePerTenantAQueries"));
suite.addTest(new AdvancedMultiTenantJunitTest("testTablePerTenantB"));
suite.addTest(new AdvancedMultiTenantJunitTest("testTablePerTenantBQueries"));
suite.addTest(new AdvancedMultiTenantJunitTest("testTablePerTenantC"));
suite.addTest(new AdvancedMultiTenantJunitTest("testTablePerTenantCQueries"));
return suite;
}
public String getMULTI_TENANT_PU() { return "multi-tenant-shared-emf"; }
public String getMULTI_TENANT_PU_123() { return "multi-tenant-123"; }
public String getMULTI_TENANT_VPD_PU() { return "multi-tenant-vpd"; }
public String getMULTI_TENANT_TABLE_PER_TENANT_PU() { return "multi-tenant-table-per-tenant"; }
public String getMULTI_TENANT_TABLE_PER_TENANT_C_PU(){ return "multi-tenant-table-per-tenant-C"; }
public EntityManager createSharedEMFEntityManager(){
return createEntityManager(getMULTI_TENANT_PU());
}
public EntityManager create123EntityManager(){
return createEntityManager(getMULTI_TENANT_PU_123());
}
public EntityManager createTenant123EntityManager(){
Map<String, String> properties = new HashMap<String, String>();
EntityManager em = null;
//properties passed in createEntityManager() won't work on server since server side entity manager is injected, so we have "eclipselink.tenant-id" in server persistence.xml
if (! isOnServer()) {
properties.putAll(JUnitTestCaseHelper.getDatabaseProperties(getMULTI_TENANT_PU_123()));
properties.put(PersistenceUnitProperties.MULTITENANT_PROPERTY_DEFAULT, "123");
em = createEntityManager(getMULTI_TENANT_PU_123(), properties);
}else{
em = create123EntityManager();
}
return em;
}
public EntityManager createVPDEntityManager(){
return createEntityManager(getMULTI_TENANT_VPD_PU());
}
public EntityManager createTableTenantEntityManager(){
return createEntityManager(getMULTI_TENANT_TABLE_PER_TENANT_PU());
}
public EntityManager createTableTenantCEntityManager(){
return createEntityManager(getMULTI_TENANT_TABLE_PER_TENANT_C_PU());
}
/**
* The setup is done as a test, both to record its failure, and to allow execution in the server.
*/
public void testSetup() {
new AdvancedMultiTenantTableCreator().replaceTables(((org.eclipse.persistence.jpa.JpaEntityManager) createSharedEMFEntityManager()).getServerSession());
}
public void testTablePerTenantA() {
EntityManager em = createTableTenantEntityManager();
try {
beginTransaction(em);
// Valid to set the table per tenant qualifier now.
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "A");
Candidate candidateA = new Candidate();
candidateA.setName("CA");
candidateA.addHonor("Raised most money");
candidateA.addHonor("Highest win margin");
candidateA.setSalary(9999999);
Supporter supporter1 = new Supporter();
supporter1.setName("Supporter1a");
SupporterInfo supporter1Info = new SupporterInfo();
supporter1Info.setDescription("Supporter1aDesc");
SupporterInfoSub supporter1InfoSub = new SupporterInfoSub();
supporter1InfoSub.setSubDescription("Supporter1aSubDesc");
supporter1Info.setSubInfo(supporter1InfoSub);
supporter1.setInfo(supporter1Info);
candidateA.addSupporter(supporter1);
Supporter supporter2 = new Supporter();
supporter2.setName("Supporter2a");
SupporterInfo supporter2Info = new SupporterInfo();
supporter2Info.setDescription("Supporter2aDesc");
SupporterInfoSub supporter2InfoSub = new SupporterInfoSub();
supporter2InfoSub.setSubDescription("Supporter2aSubDesc");
supporter2Info.setSubInfo(supporter2InfoSub);
supporter2.setInfo(supporter2Info);
candidateA.addSupporter(supporter2);
Supporter supporter3 = new Supporter();
supporter3.setName("Supporter3a");
SupporterInfo supporter3Info = new SupporterInfo();
supporter3Info.setDescription("Supporter3aDesc");
SupporterInfoSub supporter3InfoSub = new SupporterInfoSub();
supporter3InfoSub.setSubDescription("Supporter3aSubDesc");
supporter3Info.setSubInfo(supporter3InfoSub);
supporter3.setInfo(supporter3Info);
candidateA.addSupporter(supporter3);
Party party = new Party();
party.setName("Conservatives");
party.addCandidate(candidateA);
Riding riding = new Riding();
riding.setName("Ottawa");
candidateA.setRiding(riding);
// Persist our objects.
em.persist(party);
em.persist(candidateA);
em.persist(supporter1);
em.persist(supporter2);
em.persist(supporter3);
em.persist(riding);
Mason mason = new Mason();
mason.setName("FromTenantA");
mason.addAward(Helper.timestampFromDate(Helper.dateFromYearMonthDate(2009, 1, 1)), "Best pointer");
mason.addAward(Helper.timestampFromDate(Helper.dateFromYearMonthDate(2010, 5, 9)), "Least screw-ups");
Trowel trowel = new Trowel();
trowel.setType("Pointing");
mason.setTrowel(trowel);
trowel.setMason(mason);
em.persist(mason);
em.persist(trowel);
// Grab any id's for verification.
candidateAId = candidateA.getId();
ridingId = riding.getId();
partyId = party.getId();
supporter1Id = supporter1.getId();
supporter2Id = supporter2.getId();
masonId = mason.getId();
commitTransaction(em);
} catch (RuntimeException e) {
throw e;
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
public void testTablePerTenantAQueries() {
EntityManager em = createTableTenantEntityManager();
try {
beginTransaction(em);
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "A");
List resultsFromNamedQuery = em.createNamedQuery("Supporter.findAll").getResultList();
List resultsFromDynamicQuery = em.createQuery("SELECT s FROM Supporter s ORDER BY s.id DESC").getResultList();
assertTrue("Incorrect number of supporters returned from named query.", resultsFromNamedQuery.size() == 3);
assertTrue("Incorrect number of supporters returned from dynamic query.", resultsFromDynamicQuery.size() == 3);
// Test some more complex joining queries.
List<Supporter> results = em.createNamedQuery("Supporter.findBySupporterInfo").setParameter("desc", "Supporter1aDesc").getResultList();
assertFalse("No results returned.", results == null);
assertTrue("Single result not returned.", results.size() == 1);
assertTrue("Didn't return supporter1a", results.get(0).getName().equals("Supporter1a"));
results = em.createNamedQuery("Supporter.findBySupporterInfoSub").setParameter("subDesc", "Supporter3aSubDesc").getResultList();
assertFalse("No results returned.", results == null);
assertTrue("Single result not returned.", results.size() == 1);
assertTrue("Didn't return supporter3a", results.get(0).getName().equals("Supporter3a"));
commitTransaction(em);
} catch (RuntimeException e) {
throw e;
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
public void testTablePerTenantB() {
EntityManager em = createTableTenantEntityManager();
try {
beginTransaction(em);
// Valid to set the table per tenant qualifier now.
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "B");
// Should not find these ...
assertNull("CandidateA was found from tenant B.", em.find(Candidate.class, candidateAId));
assertNull("Supporter1 was found from tenant B.", em.find(Supporter.class, supporter1Id));
assertNull("Supporter2 was found from tenant B.", em.find(Supporter.class, supporter2Id));
assertNull("Mason was found from tenant B.", em.find(Mason.class, masonId));
// Should find these ...
Riding riding = em.find(Riding.class, ridingId);
assertNotNull("Riding was not found from tenant B", riding);
Party party = em.find(Party.class, partyId);
assertNotNull("Party was not found from tenant B", party);
// TODO: can't do this (would have to initialize the mapping from party again to the new descriptor.
// future implementation maybe.
//assertTrue("Party had candidates", party.getCandidates().isEmpty());
Candidate candidateB = new Candidate();
candidateB.setName("CB");
candidateB.setSalary(100);
em.persist(candidateB);
commitTransaction(em);
em.clear();
clearCache(getMULTI_TENANT_TABLE_PER_TENANT_PU());
beginTransaction(em);
// Valid to set the table per tenant qualifier now.
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "B");
Candidate candidateBRefreshed = em.find(Candidate.class, candidateB.getId());
assertNull("Candidate B has a Party when he shouldn't have.", candidateBRefreshed.getParty());
assertNull("Candidate B has a Riding when he shouldn't have.", candidateBRefreshed.getRiding());
assertTrue("Candidate B had supporters when he shouldn't have.", candidateBRefreshed.getSupporters().isEmpty());
assertTrue("Candidate B had honors when he shouldn't have.", candidateBRefreshed.getHonors().isEmpty());
assertTrue("Candidate B had the incorrect salary.", candidateBRefreshed.getSalary() == 100);
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
public void testTablePerTenantBQueries() {
EntityManager em = createTableTenantEntityManager();
try {
beginTransaction(em);
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "B");
List resultsFromNamedQuery = em.createNamedQuery("Supporter.findAll").getResultList();
List resultsFromDynamicQuery = em.createQuery("SELECT s FROM Supporter s ORDER BY s.id DESC").getResultList();
assertTrue("Incorrect number of supporters returned from named query.", resultsFromNamedQuery.isEmpty());
assertTrue("Incorrect number of supporters returned from dynamic query.", resultsFromDynamicQuery.isEmpty());
commitTransaction(em);
} catch (RuntimeException e) {
throw e;
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
public void testTablePerTenantC() {
// Tenant is set in the persistence.xml file.
EntityManager em = createTableTenantCEntityManager();
try {
beginTransaction(em);
Candidate candidate = new Candidate();
candidate.setName("C");
candidate.addHonor("Raised most money");
candidate.addHonor("Highest win margin");
candidate.setSalary(9999999);
Supporter supporter1 = new Supporter();
supporter1.setName("Supporter1c");
candidate.addSupporter(supporter1);
Supporter supporter2 = new Supporter();
supporter2.setName("Supporter2c");
candidate.addSupporter(supporter2);
Party party = new Party();
party.setName("Conservatives");
party.addCandidate(candidate);
Riding riding = new Riding();
riding.setName("Ottawa");
candidate.setRiding(riding);
// Persist our objects.
em.persist(party);
em.persist(candidate);
em.persist(supporter2);
em.persist(supporter1);
em.persist(riding);
Mason mason = new Mason();
mason.setName("FromTenantC");
mason.addAward(Helper.timestampFromDate(Helper.dateFromYearMonthDate(2009, 1, 1)), "Best pointer");
mason.addAward(Helper.timestampFromDate(Helper.dateFromYearMonthDate(2010, 5, 9)), "Least screw-ups");
Trowel trowel = new Trowel();
trowel.setType("Pointing");
mason.setTrowel(trowel);
trowel.setMason(mason);
em.persist(mason);
em.persist(trowel);
// Grab any id's for verification.
candidateAId = candidate.getId();
ridingId = riding.getId();
partyId = party.getId();
supporter1Id = supporter1.getId();
supporter2Id = supporter2.getId();
masonId = mason.getId();
commitTransaction(em);
} catch (RuntimeException e) {
throw e;
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
public void testTablePerTenantCQueries() {
EntityManager em = createTableTenantCEntityManager();
try {
beginTransaction(em);
List resultsFromNamedQuery = em.createNamedQuery("Supporter.findAll").getResultList();
List resultsFromDynamicQuery = em.createQuery("SELECT s FROM Supporter s ORDER BY s.id DESC").getResultList();
assertTrue("Incorrect number of supporters returned from named query.", resultsFromNamedQuery.size() == 2);
assertTrue("Incorrect number of supporters returned from dynamic query.", resultsFromDynamicQuery.size() == 2);
commitTransaction(em);
} catch (RuntimeException e) {
throw e;
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
}
public void testCreateMafiaFamily707() {
EntityManager em = createSharedEMFEntityManager();
try {
beginTransaction(em);
//on server side, you have to set the em properties after transaction begins
em.setProperty("tenant.id", "707");
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "707");
MafiaFamily family = new MafiaFamily();
family.setName("Gonzo");
family.setRevenue(10000000.00);
family.addTag("firstTag");
family.addTag("secondTag");
family.addTag("thirdTag");
Boss boss = new Boss();
boss.setFirstName("707");
boss.setLastName("Boss");
boss.setGender(Mafioso.Gender.Male);
Underboss underboss = new Underboss();
underboss.setFirstName("Under");
underboss.setLastName("Boss");
underboss.setGender(Mafioso.Gender.Male);
Capo capo1 = new Capo();
capo1.setFirstName("Capo");
capo1.setLastName("Giggaloo");
capo1.setGender(Mafioso.Gender.Female);
Capo capo2 = new Capo();
capo2.setFirstName("Capo");
capo2.setLastName("CrazyGlue");
capo2.setGender(Mafioso.Gender.Male);
Soldier soldier1 = new Soldier();
soldier1.setFirstName("Soldier");
soldier1.setLastName("One");
soldier1.setGender(Mafioso.Gender.Female);
Soldier soldier2 = new Soldier();
soldier2.setFirstName("Soldier");
soldier2.setLastName("Two");
soldier2.setGender(Mafioso.Gender.Male);
Soldier soldier3 = new Soldier();
soldier3.setFirstName("Soldier");
soldier3.setLastName("Three");
soldier3.setGender(Mafioso.Gender.Male);
Soldier soldier4 = new Soldier();
soldier4.setFirstName("Soldier");
soldier4.setLastName("Four");
soldier4.setGender(Mafioso.Gender.Male);
Soldier soldier5 = new Soldier();
soldier5.setFirstName("Soldier");
soldier5.setLastName("Four");
soldier5.setGender(Mafioso.Gender.Female);
Contract contract1 = new Contract();
contract1.setDescription("Whack 007 family boss");
Contract contract2 = new Contract();
contract2.setDescription("Acquire fully-automatic guns");
Contract contract3 = new Contract();
contract3.setDescription("Steal some money");
// Populate the relationships.
contract1.addSoldier(soldier1);
contract1.addSoldier(soldier5);
contract2.addSoldier(soldier1);
contract2.addSoldier(soldier3);
contract2.addSoldier(soldier5);
contract3.addSoldier(soldier2);
contract3.addSoldier(soldier3);
contract3.addSoldier(soldier4);
contract3.addSoldier(soldier5);
boss.setUnderboss(underboss);
capo1.setUnderboss(underboss);
capo2.setUnderboss(underboss);
capo1.addSoldier(soldier1);
capo1.addSoldier(soldier2);
capo2.addSoldier(soldier3);
capo2.addSoldier(soldier4);
capo2.addSoldier(soldier5);
underboss.addCapo(capo1);
underboss.addCapo(capo2);
family.addMafioso(boss);
family.addMafioso(underboss);
family.addMafioso(capo1);
family.addMafioso(capo2);
family.addMafioso(soldier1);
family.addMafioso(soldier2);
family.addMafioso(soldier3);
family.addMafioso(soldier4);
family.addMafioso(soldier5);
// Will cascade through the whole family.
em.persist(family);
// Store the ids to verify
family707 = family.getId();
family707Mafiosos.add(boss.getId());
family707Mafiosos.add(underboss.getId());
family707Mafiosos.add(capo1.getId());
family707Mafiosos.add(capo2.getId());
family707Mafiosos.add(soldier1.getId());
family707Mafiosos.add(soldier2.getId());
family707Mafiosos.add(soldier3.getId());
family707Mafiosos.add(soldier4.getId());
family707Mafiosos.add(soldier5.getId());
family707Contracts.add(contract1.getId());
family707Contracts.add(contract2.getId());
family707Contracts.add(contract3.getId());
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
public void testCreateMafiaFamily007() {
EntityManager em = createSharedEMFEntityManager();
try {
beginTransaction(em);
//on server side, you have to set the em properties after transaction begins
em.setProperty("tenant.id", "007");
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "007");
MafiaFamily family = new MafiaFamily();
family.setName("Bond");
family.setRevenue(987654321.03);
family.addTag("tag1");
family.addTag("tag2");
family.addTag("tag3");
family.addTag("tag4");
family.addTag("tag5");
Boss boss = new Boss();
boss.setFirstName("007");
boss.setLastName("Boss");
boss.setGender(Mafioso.Gender.Female);
Underboss underboss = new Underboss();
underboss.setFirstName("Second");
underboss.setLastName("InCommand");
underboss.setGender(Mafioso.Gender.Female);
Capo capo1 = new Capo();
capo1.setFirstName("Capo");
capo1.setLastName("Lubey");
capo1.setGender(Mafioso.Gender.Male);
Capo capo2 = new Capo();
capo2.setFirstName("Capo");
capo2.setLastName("Greasy");
capo2.setGender(Mafioso.Gender.Female);
Soldier soldier1 = new Soldier();
soldier1.setFirstName("First");
soldier1.setLastName("Grunt");
soldier1.setGender(Mafioso.Gender.Male);
Soldier soldier2 = new Soldier();
soldier2.setFirstName("Second");
soldier2.setLastName("Grunt");
soldier2.setGender(Mafioso.Gender.Female);
Soldier soldier3 = new Soldier();
soldier3.setFirstName("Third");
soldier3.setLastName("Grunt");
soldier3.setGender(Mafioso.Gender.Female);
Soldier soldier4 = new Soldier();
soldier4.setFirstName("Fourth");
soldier4.setLastName("Grunt");
soldier4.setGender(Mafioso.Gender.Female);
Soldier soldier5 = new Soldier();
soldier5.setFirstName("Fifth");
soldier5.setLastName("Grunt");
soldier5.setGender(Mafioso.Gender.Male);
Soldier soldier6 = new Soldier();
soldier6.setFirstName("Sixth");
soldier6.setLastName("Grunt");
soldier6.setGender(Mafioso.Gender.Male);
Soldier soldier7 = new Soldier();
soldier7.setFirstName("Seventh");
soldier7.setLastName("Grunt");
soldier7.setGender(Mafioso.Gender.Male);
Contract contract1 = new Contract();
contract1.setDescription("Whack 707 family boss");
Contract contract2 = new Contract();
contract2.setDescription("Acquire semi-automatic guns");
Contract contract3 = new Contract();
contract3.setDescription("Set up new financing deals");
// Populate the relationships.
contract1.addSoldier(soldier1);
contract1.addSoldier(soldier5);
contract2.addSoldier(soldier1);
contract2.addSoldier(soldier3);
contract2.addSoldier(soldier7);
contract3.addSoldier(soldier2);
contract3.addSoldier(soldier3);
contract3.addSoldier(soldier4);
contract3.addSoldier(soldier5);
boss.setUnderboss(underboss);
capo1.setUnderboss(underboss);
capo2.setUnderboss(underboss);
capo1.addSoldier(soldier1);
capo1.addSoldier(soldier2);
capo2.addSoldier(soldier3);
capo2.addSoldier(soldier4);
capo2.addSoldier(soldier5);
capo2.addSoldier(soldier6);
capo2.addSoldier(soldier7);
underboss.addCapo(capo1);
underboss.addCapo(capo2);
family.addMafioso(boss);
family.addMafioso(underboss);
family.addMafioso(capo1);
family.addMafioso(capo2);
family.addMafioso(soldier1);
family.addMafioso(soldier2);
family.addMafioso(soldier3);
family.addMafioso(soldier4);
family.addMafioso(soldier5);
family.addMafioso(soldier6);
family.addMafioso(soldier7);
// Will cascade through the whole family.
em.persist(family);
family007 = family.getId();
family007Mafiosos.add(boss.getId());
family007Mafiosos.add(underboss.getId());
family007Mafiosos.add(capo1.getId());
family007Mafiosos.add(capo2.getId());
family007Mafiosos.add(soldier1.getId());
family007Mafiosos.add(soldier2.getId());
family007Mafiosos.add(soldier3.getId());
family007Mafiosos.add(soldier4.getId());
family007Mafiosos.add(soldier5.getId());
family007Mafiosos.add(soldier6.getId());
family007Mafiosos.add(soldier7.getId());
family007Contracts.add(contract1.getId());
family007Contracts.add(contract2.getId());
family007Contracts.add(contract3.getId());
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
/**
* This test is expected to fail.
*/
public void testCreateEMF123WithoutAllTenantPropertiesSet() {
EntityManager em = null;
boolean exceptionCaught = false;
try {
em = create123EntityManager();
} catch (RuntimeException e) {
exceptionCaught = true;
} finally {
if (em != null) {
closeEntityManager(em);
}
closeEntityManagerFactory(getMULTI_TENANT_PU_123());
}
assertTrue("No exception received on a non shared emf without all tenant properties provided", exceptionCaught);
}
public void testCreateMafiaFamily123() {
EntityManager em = createTenant123EntityManager();
try {
beginTransaction(em);
MafiaFamily family = new MafiaFamily();
family.setName("Galore");
family.setRevenue(4321.03);
family.addTag("newtag1");
Boss boss = new Boss();
boss.setFirstName("Kitty");
boss.setLastName("Galore");
boss.setGender(Mafioso.Gender.Female);
boss.addReward("Reward 1");
boss.addReward("Reward 2");
boss.setAddress(new Address("1st Street", "Ottawa", "Ontario", "Canada", "B1T 2Y1"));
Underboss underboss = new Underboss();
underboss.setFirstName("Number2");
underboss.setLastName("Galore");
underboss.setGender(Mafioso.Gender.Male);
underboss.addReward("Reward 3");
underboss.addReward("Reward 4");
underboss.setAddress(new Address("2nd Street", "Ottawa", "Ontario", "Canada", "B1T 2Y2"));
Capo capo1 = new Capo();
capo1.setFirstName("Capo");
capo1.setLastName("Galore");
capo1.setGender(Mafioso.Gender.Male);
capo1.setAddress(new Address("3rd Street", "Ottawa", "Ontario", "Canada", "B1T 2Y3"));
Capo capo2 = new Capo();
capo2.setFirstName("Drill");
capo2.setLastName("Bit");
capo2.setGender(Mafioso.Gender.Male);
capo2.setAddress(new Address("4th Street", "Ottawa", "Ontario", "Canada", "B1T 2Y4"));
Soldier soldier1 = new Soldier();
soldier1.setFirstName("Grunt");
soldier1.setLastName("Galore");
soldier1.setGender(Mafioso.Gender.Male);
soldier1.addReward("Reward 5");
soldier1.addReward("Reward 6");
soldier1.addReward("Reward 7");
soldier1.addReward("Reward 8");
soldier1.setAddress(new Address("5th Street", "Ottawa", "Ontario", "Canada", "B1T 2Y5"));
Soldier soldier2 = new Soldier();
soldier2.setFirstName("Hammer");
soldier2.setLastName("Head");
soldier2.setGender(Mafioso.Gender.Male);
soldier2.addReward("Reward 9");
soldier2.addReward("Reward 10");
soldier2.setAddress(new Address("6th Street", "Ottawa", "Ontario", "Canada", "B1T 2Y6"));
Contract contract1 = new Contract();
contract1.setDescription("Whack all other family bosses");
Contract contract2 = new Contract();
contract2.setDescription("Pillage, pillage, pillage!");
// Populate the relationships.
contract1.addSoldier(soldier1);
contract2.addSoldier(soldier1);
boss.setUnderboss(underboss);
capo1.setUnderboss(underboss);
capo1.addSoldier(soldier1);
capo2.addSoldier(soldier2);
underboss.addCapo(capo1);
underboss.addCapo(capo2);
family.addMafioso(boss);
family.addMafioso(underboss);
family.addMafioso(capo1);
family.addMafioso(capo2);
family.addMafioso(soldier1);
family.addMafioso(soldier2);
// Will cascade through the whole family.
em.persist(family);
capo123Id = capo1.getId();
soldier123Id = soldier1.getId();
family123 = family.getId();
family123Mafiosos.add(boss.getId());
family123Mafiosos.add(underboss.getId());
family123Mafiosos.add(capo1.getId());
family123Mafiosos.add(soldier1.getId());
family123Contracts.add(contract1.getId());
family123Contracts.add(contract2.getId());
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
public void testValidateMafiaFamily707() {
EntityManager em = createSharedEMFEntityManager();
try {
validateMafiaFamily707(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
public void testValidateMafiaFamily007() {
EntityManager em = createSharedEMFEntityManager();
try {
validateMafiaFamily007(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
public void testValidateMafiaFamily707and007WithSameEM() {
EntityManager em = createSharedEMFEntityManager();
try {
validateMafiaFamily707(em);
validateMafiaFamily007(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
public void testValidateMafiaFamily123() {
EntityManager em = createTenant123EntityManager();
try {
clearCache(getMULTI_TENANT_PU_123());
em.clear();
MafiaFamily family = em.find(MafiaFamily.class, family123);
assertNotNull("The Mafia Family with id: " + family123 + ", was not found", family);
assertTrue("The Mafia Family had an incorrect number of tags [" + family.getTags().size() + "], expected [1]", family.getTags().size() == 1);
assertNull("The Mafia Family with id: " + family707 + ", was found (when it should not have been)", em.find(MafiaFamily.class, family707));
assertNull("The Mafia Family with id: " + family007 + ", was found (when it should not have been)", em.find(MafiaFamily.class, family007));
assertFalse("No mafiosos part of 123 family", family.getMafiosos().isEmpty());
// See if we can find any members of the other family.
for (Integer id : family707Mafiosos) {
assertNull("Found family 707 mafioso.", em.find(Mafioso.class, id));
}
// Try a native sql query. Should get an exception since the
// eclipselink.jdbc.allow-native-sql-queries property is set to
// false for this PU.
boolean exceptionCaught = false;
List mafiaFamilies = null;
try {
mafiaFamilies = em.createNativeQuery("select * from JPA_MAFIA_FAMILY").getResultList();
} catch (Exception e) {
exceptionCaught = true;
}
assertTrue("No exception was caught from issuing a native query.", exceptionCaught);
exceptionCaught = false;
try {
mafiaFamilies = em.createNamedQuery("findSQLMafiaFamilies").getResultList();
} catch (Exception e) {
exceptionCaught = true;
}
assertTrue("No exception was caught from issuing a named native query.", exceptionCaught);
// Query directly for the boss from the other family.
Boss otherBoss = em.find(Boss.class, family707Mafiosos.get(0));
assertNull("Found family 707 boss.", otherBoss);
// See if we can find any contracts of the other family.
for (Integer id : family707Contracts) {
assertNull("Found family 707 contract. ", em.find(Contract.class, id));
}
// Try a select named query
List families = em.createNamedQuery("findAllMafiaFamilies").getResultList();
assertTrue("Incorrect number of families were returned [" + families.size() + "], expected [1]", families.size() == 1);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
protected void validateMafiaFamily007(EntityManager em) {
clearCache(getMULTI_TENANT_PU());
em.clear();
beginTransaction(em);
em.setProperty("tenant.id", "007");
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "007");
MafiaFamily family = em.find(MafiaFamily.class, family007);
assertNotNull("The Mafia Family with id: " + family007 + ", was not found", family);
assertTrue("The Mafia Family had an incorrect number of tags [" + family.getTags().size() + "], expected [5]", family.getTags().size() == 5);
assertNull("The Mafia Family with id: " + family707 + ", was found (when it should not have been)", em.find(MafiaFamily.class, family707));
assertNull("The Mafia Family with id: " + family123 + ", was found (when it should not have been)", em.find(MafiaFamily.class, family123));
assertFalse("No mafiosos part of 007 family", family.getMafiosos().isEmpty());
// See if we can find any members of the other family.
for (Integer id : family707Mafiosos) {
assertNull("Found family 707 mafioso.", em.find(Mafioso.class, id));
}
// Query directly for the boss from the other family.
Boss otherBoss = em.find(Boss.class, family707Mafiosos.get(0));
assertNull("Found family 707 boss.", otherBoss);
// See if we can find any contracts of the other family.
for (Integer id : family707Contracts) {
assertNull("Found family 707 contract.", em.find(Contract.class, id));
}
// Read and validate our contracts
List<Contract> contracts = em.createNamedQuery("FindAllContracts").getResultList();
assertTrue("Incorrect number of contracts were returned [" + contracts.size() + "], expected[3]", contracts.size() == 3);
for (Contract contract : contracts) {
assertFalse("Contract description was voided.", contract.getDescription().equals("voided"));
}
// Try a select named query
List families = em.createNamedQuery("findAllMafiaFamilies").getResultList();
assertTrue("Incorrect number of families were returned [" + families.size() + "], expected [1]", families.size() == 1);
// Find our boss and make sure his name has not been compromised from the 707 family.
Boss boss = em.find(Boss.class, family007Mafiosos.get(0));
assertFalse("The Boss name has been compromised", boss.getFirstName().equals("Compromised"));
commitTransaction(em);
}
protected void validateMafiaFamily707(EntityManager em) {
clearCache(getMULTI_TENANT_PU());
em.clear();
beginTransaction(em);
em.setProperty("tenant.id", "707");
em.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "707");
MafiaFamily family = em.find(MafiaFamily.class, family707);
assertNotNull("The Mafia Family with id: " + family707 + ", was not found", family);
assertTrue("The Mafia Family had an incorrect number of tags [" + family.getTags().size() + "], expected [3]", family.getTags().size() == 3);
assertNull("The Mafia Family with id: " + family007 + ", was found (when it should not have been)", em.find(MafiaFamily.class, family007));
assertNull("The Mafia Family with id: " + family123 + ", was found (when it should not have been)", em.find(MafiaFamily.class, family123));
assertFalse("No mafiosos part of 707 family", family.getMafiosos().isEmpty());
// See if we can find any members of the other family.
for (Integer id : family007Mafiosos) {
assertNull("Found family 007 mafioso.", em.find(Mafioso.class, id));
}
// Query directly for the boss from the other family.
Boss otherBoss = em.find(Boss.class, family007Mafiosos.get(0));
assertNull("Found family 007 boss.", otherBoss);
// See if we can find any contracts of the other family.
for (Integer id : family007Contracts) {
assertNull("Found family 007 contract.", em.find(Contract.class, id));
}
// Try deleting a contract from the 007 family.
Query deleteQuery = em.createNamedQuery("DeleteContractByPrimaryKey");
deleteQuery.setParameter("id", family007Contracts.get(0));
int result = deleteQuery.executeUpdate();
assertTrue("Was able to delete a contract from the 007 family", result == 0);
// Update all our contract descriptions to be 'voided'
Query updateAllQuery = em.createNamedQuery("UpdateAllContractDescriptions");
updateAllQuery.executeUpdate();
// Need to check that tenant id column is present
assertTrue("Tenant discriminator column not found in update all query", ((EJBQueryImpl) updateAllQuery).getDatabaseQuery().getCall().getSQLString().contains("TENANT_ID"));
// Read and validate the contracts
List<Contract> contracts = em.createNamedQuery("FindAllContracts").getResultList();
int contractNumber = contracts.size();
assertTrue("Incorrect number of contracts were returned [" + contracts.size() + "], expected [3]", contracts.size() == 3);
for (Contract contract : contracts) {
assertTrue("Contract description was not voided.", contract.getDescription().equals("voided"));
}
// See how many soldiers are returned from a jpql query
List soldiers = em.createQuery("SELECT s from Soldier s").getResultList();
assertTrue("Incorrect number of soldiers were returned [" + soldiers.size() + "], expected [5]", soldiers.size() == 5);
if(getServerSession(getMULTI_TENANT_PU()).getPlatform().isSymfoware()) {
getServerSession(getMULTI_TENANT_PU()).logMessage("Test AdvancedMultiTenantJunitTest partially skipped for this platform, "
+"which uses UpdateAll internally to check tenant-id when updating an entity using JOINED inheritance strategy. "
+"Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
commitTransaction(em);
return;
}
// We know what the boss's id is for the 007 family to try to update him from the 707 pu.
// The 007 family is validated after this test.
Query query = em.createNamedQuery("UpdateBossName");
query.setParameter("name", "Compromised");
query.setParameter("id", family007Mafiosos.get(0));
query.executeUpdate();
commitTransaction(em);
}
public void testComplexMultitenantQueries() {
EntityManager em = createTenant123EntityManager();
try {
clearCache(getMULTI_TENANT_PU_123());
em.clear();
// Try passing in a sub entity as a parameter.
try {
Query q = em.createQuery("SELECT s FROM Soldier s WHERE s.capo=?1");
SubCapo subCapo = new SubCapo();
subCapo.setId(capo123Id);
q.setParameter(1, subCapo);
List<Soldier> soldiers = q.getResultList();
assertTrue("Incorrect number of soldiers returned [" + soldiers.size() +"], expected [1]", soldiers.size() == 1);
assertTrue("Mafioso returned was not a soldier", soldiers.get(0).isSoldier());
assertTrue("Soldier returned was not the expected soldier", soldiers.get(0).getId() == soldier123Id);
} catch (Exception e) {
fail("Exception encountered on named parameter query (with tenant discriminator columns) : " + e);
}
// Try a join fetch
try {
TypedQuery<MafiaFamily> q = em.createQuery("SELECT m FROM MafiaFamily m ORDER BY m.id DESC", MafiaFamily.class);
q.setHint(QueryHints.FETCH, "m.mafiosos");
q.getResultList();
} catch (Exception e) {
fail("Exception encountered on join fetch query (with tenant discriminator columns): " + e);
}
// Try a nested join fetch
try {
TypedQuery<MafiaFamily> q = em.createQuery("SELECT f FROM MafiaFamily f ORDER BY f.id ASC", MafiaFamily.class);
q.setHint(QueryHints.FETCH, "f.mafiosos.rewards");
q.getResultList();
} catch (Exception e) {
fail("Exception encountered on nested join fetch query (with tenant discriminator columns): " + e);
}
// Try a batch fetch
try {
TypedQuery<MafiaFamily> query = em.createQuery("SELECT f FROM MafiaFamily f", MafiaFamily.class);
query.setHint(QueryHints.BATCH, "f.mafiosos");
List<MafiaFamily> families = query.getResultList();
// Should only be one family
assertTrue("Incorrect number of families returned [" + families.size() +"], expected [1]", families.size() == 1);
int size = families.get(0).getMafiosos().size();
assertTrue("Incorrect number of mafiosos returned [" + size + "], expected [6]", size == 6);
} catch (Exception e) {
fail("Exception encountered on batch fetch query (with tenant discriminator columns): " + e);
}
// Try a multiple select
try {
Query query = em.createQuery("SELECT m.address, m.family FROM Mafioso m WHERE m.address.city = 'Ottawa' AND m.family.name LIKE 'Galore'", MafiaFamily.class);
List results = query.getResultList();
int size = results.size();
assertTrue("Incorrect number of results returned [" + size + "], expected [6]", size == 6);
} catch (Exception e) {
fail("Exception encountered on mulitple select statement (with tenant discriminator columns): " + e);
}
// Try a delete all on single table (Contracts)
try {
beginTransaction(em);
int contracts = em.createNamedQuery("FindAllContracts").getResultList().size();
int deletes = em.createNamedQuery("DeleteAllContracts").executeUpdate();
assertTrue("Incorrect number of contracts deleted [" + deletes + "], expected [" + contracts + "]", deletes == 2);
commitTransaction(em);
} catch (Exception e) {
fail("Exception encountered on delete all query with single table (with tenant discriminator columns): " + e);
}
if(getServerSession(getMULTI_TENANT_PU_123()).getPlatform().isSymfoware()) {
getServerSession(getMULTI_TENANT_PU_123()).logMessage("Test AdvancedMultiTenantJunitTest partially skipped for this platform, "
+"Symfoware doesn't support UpdateAll/DeleteAll on multi-table objects (see rfe 298193).");
} else {
// Try a delete all on multiple table (MafiaFamily)
try {
beginTransaction(em);
List<MafiaFamily> allFamilies = em.createNamedQuery("findAllMafiaFamilies").getResultList();
int families = allFamilies.size();
assertTrue("More than one family was found ["+ families +"]", families == 1);
Query deleteQuery = em.createNamedQuery("DeleteAllMafiaFamilies");
deleteQuery.setHint(QueryHints.ALLOW_NATIVE_SQL_QUERY, true);
int deletes = deleteQuery.executeUpdate();
assertTrue("Incorrect number of families deleted [" + deletes + "], expected [" + families + "]", deletes == 1);
commitTransaction(em);
} catch (Exception e) {
fail("Exception encountered on delete all query with multiple table (with tenant discriminator columns): " + e);
}
}
} finally {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
closeEntityManager(em);
}
// Some verification of what was deleted.
EntityManager em007 = createSharedEMFEntityManager();
try {
List<MafiaFamily> families = em007.createNativeQuery("select * from JPA_MAFIA_FAMILY", MafiaFamily.class).getResultList();
assertTrue("Incorrect number of families found through SQL [" + families.size() + "], expected [2]", families.size() == 2);
// Clear out the shared cache with what we read through native SQL.
clearCache(getMULTI_TENANT_PU());
em007.clear();
beginTransaction(em007);
em007.setProperty("tenant.id", "007");
em007.setProperty(EntityManagerProperties.MULTITENANT_PROPERTY_DEFAULT, "007");
MafiaFamily family = em007.find(MafiaFamily.class, family007);
assertFalse("Family 007 tags were nuked in delete all query above!", family.getTags().isEmpty());
assertFalse("Family 007 revenue was nuked in delete all query above!", family.getRevenue() == null);
commitTransaction(em007);
} catch (Exception e) {
fail("Exception caught: " + e);
} finally {
if (isTransactionActive(em007)) {
rollbackTransaction(em007);
}
closeEntityManager(em007);
}
}
/**
* This test will try to DDL generate on deploy. Meaning once we try to
* access the VPD PU we'll get an exception if we are not an oracle platform
* so check before throwing an exception.
*
* VPD is currently supported only on Oracle.
*/
public void testVPDEMPerTenant() {
EntityManager em1 = null;
EntityManager em2 = null;
try {
em1 = createVPDEntityManager();
em1.setProperty("tenant.id", "bsmith@here.com");
em2 = createVPDEntityManager();
em2.setProperty("tenant.id", "gdune@there.ca");
testInsertTask(em1, "blah", false);
testInsertTask(em2, "halb", false);
assertTrue("Found more than one result", em1.createQuery("Select t from Task t").getResultList().size() == 1);
assertTrue("Found more than one result", em2.createQuery("Select t from Task t").getResultList().size() == 1);
Task task1 = testInsertTaskWithOneSubtask(em1, "Rock that Propsal", false, "Write Proposal", false);
assertNotNull(em1.find(Task.class, task1.getId()));
assertNull(em2.find(Task.class, task1.getId())); // negative test
Task task3 = testInsertTask(em2, "mow lawn", true);
assertNull(em1.find(Task.class, task3.getId())); // negative test
assertNotNull(em2.find(Task.class, task3.getId()));
SubTask task4 = testInsertSubTaskObject(em1, "SubTask Object Creation", true);
assertNotNull(em1.find(SubTask.class, task4.getId()));
assertNull(em2.find(SubTask.class, task4.getId())); // negative test
} catch (RuntimeException e) {
if (em1 != null && isTransactionActive(em1)){
rollbackTransaction(em1);
}
if (em2 != null && isTransactionActive(em2)){
rollbackTransaction(em2);
}
if (! getPlatform(getMULTI_TENANT_VPD_PU()).isOracle()) {
warning("VPD tests currently run only on an Oracle platform");
} else {
throw e;
}
} finally {
if (em1 != null) {
closeEntityManager(em1);
}
if (em2 != null) {
closeEntityManager(em2);
}
}
}
public void testMultitenantPrimaryKeyWithIdClass() {
EntityManager em = createSharedEMFEntityManager();
PhoneNumber number = new PhoneNumber();;
number.setAreaCode("613");
number.setNumber("123-4567");
number.setType("Home");
try {
beginTransaction(em);
// On server side, you have to set the em properties after
// transaction begins
em.setProperty("tenant.id", "707");
em.persist(number);
commitTransaction(em);
// This should hit the cache.
beginTransaction(em);
em.setProperty("tenant.id", "707");
PhoneNumber refreshedNumber = em.find(PhoneNumber.class, number.buildPK());
rollbackTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
public void testMultitenantOneToOneReadObjectRead() {
EntityManager em = createSharedEMFEntityManager();
try {
beginTransaction(em);
em.setProperty("tenant.id", "371453");
Envelope envelope = new Envelope();
envelope.setColor("Red");
Card card = new Card();
card.setPrice(2.99);
card.setColor("Yellow");
card.setPrintYear(2012);
card.setOccasion("Sympathy");
card.setFrontCaption("Get well soon");
card.setInsideCaption("Here's to a speedy recovery");
card.setEnvelope(envelope);
envelope.setCard(card);
// Will cascade to the envelope
em.persist(card);
commitTransaction(em);
em.clear();
clearCache(getMULTI_TENANT_PU());
beginTransaction(em);
em.setProperty("tenant.id", "371453");
envelope = em.merge(envelope);
commitTransaction(em);
em.clear();
clearCache(getMULTI_TENANT_PU());
beginTransaction(em);
em.setProperty("tenant.id", "371453");
card = em.merge(card);
commitTransaction(em);
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
private Task testInsertTask(EntityManager em, String description, boolean isCompleted) {
beginTransaction(em);
Task task = new Task();
task.setDescription(description);
task.setCompleted(isCompleted);
em.persist(task);
commitTransaction(em);
return task;
}
private Task testInsertTaskWithOneSubtask(EntityManager em, String description, boolean isCompleted, String subtaskDesc, boolean isSubtaskCompleted) {
beginTransaction(em);
Task task = new Task();
Task subtask = new Task();
task.setDescription(description);
task.setCompleted(isCompleted);
subtask.setDescription(subtaskDesc);
subtask.setCompleted(isSubtaskCompleted);
task.addSubtask(subtask);
em.persist(subtask);
em.persist(task);
commitTransaction(em);
return task;
}
private SubTask testInsertSubTaskObject(EntityManager em, String description, boolean isCompleted) {
beginTransaction(em);
SubTask subTask = new SubTask();
subTask.setDescription(description);
subTask.setCompleted(isCompleted);
em.persist(subTask);
commitTransaction(em);
return subTask;
}
}