blob: dcb2677c8691f3d049e122b16d88b594df326be8 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2012, 2015 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* 11/19/2012-2.5 Guy Pelletier
* - 389090: JPA 2.1 DDL Generation Support (foreign key metadata support)
* 11/22/2012-2.5 Guy Pelletier
* - 389090: JPA 2.1 DDL Generation Support (index metadata support)
* 12/07/2012-2.5 Guy Pelletier
* - 389090: JPA 2.1 DDL Generation Support (foreign key metadata support)
* 01/23/2013-2.5 Guy Pelletier
* - 350487: JPA 2.1 Specification defined support for Stored Procedure Calls
* 04/12/2013-2.5 Guy Pelletier
* - 405640: JPA 2.1 schema generation drop operation fails to include dropping defaulted fk constraints.
******************************************************************************/
package org.eclipse.persistence.testing.tests.jpa21.advanced;
import java.util.Date;
import java.util.Map;
import javax.persistence.EntityManager;
import org.eclipse.persistence.descriptors.ClassDescriptor;
import org.eclipse.persistence.internal.helper.DatabaseTable;
import org.eclipse.persistence.internal.queries.MappedKeyMapContainerPolicy;
import org.eclipse.persistence.mappings.DirectCollectionMapping;
import org.eclipse.persistence.mappings.DirectMapMapping;
import org.eclipse.persistence.mappings.ForeignReferenceMapping;
import org.eclipse.persistence.mappings.ManyToManyMapping;
import org.eclipse.persistence.mappings.OneToManyMapping;
import org.eclipse.persistence.mappings.OneToOneMapping;
import org.eclipse.persistence.sessions.server.ServerSession;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.Coach;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.Organizer;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.Race;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.Responsibility;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.Runner;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.RunnerInfo;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.RunnerStatus;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.Shoe;
import org.eclipse.persistence.testing.models.jpa21.advanced.ddl.Sprinter;
import org.eclipse.persistence.testing.models.jpa21.advanced.enums.Health;
import org.eclipse.persistence.testing.models.jpa21.advanced.enums.Level;
import org.eclipse.persistence.testing.models.jpa21.advanced.enums.RunningStatus;
import org.eclipse.persistence.tools.schemaframework.ForeignKeyConstraint;
import junit.framework.TestSuite;
import junit.framework.Test;
public class ForeignKeyTestSuite extends JUnitTestCase {
public ForeignKeyTestSuite() {}
public ForeignKeyTestSuite(String name) {
super(name);
setPuName("MulitPU-2");
}
protected void assertForeignKeyConstraint(String name, String definition, DatabaseTable table) {
assertTrue("No foreign key constraints were found on table [" + table.getName()+ "]", table.hasForeignKeyConstraints());
ForeignKeyConstraint constraint = table.getForeignKeyConstraint(name);
assertNotNull("The foreign key constraint named [" + name + "] was not found on table [" + table.getName() + "]", constraint);
assertFalse("The foreign key definition for the constraint named [" + name + "] on table [" + table + "] was null.", constraint.getForeignKeyDefinition() == null);
assertTrue("The foreign key definition for the constraint named [" + name + "] on table [" + table + "] was set as [" + constraint.getForeignKeyDefinition() + " ], but was expecting [" + definition + " ]", constraint.getForeignKeyDefinition().equals(definition));
}
/**
* Return the the persistence unit name for this test suite.
*/
@Override
public String getPersistenceUnitName() {
return "MulitPU-2";
}
public static Test suite() {
TestSuite suite = new TestSuite();
suite.setName("ForeignKeyTestSuite");
suite.addTest(new ForeignKeyTestSuite("testInheritancePrimaryKeyForeignKey"));
suite.addTest(new ForeignKeyTestSuite("testCollectionTableForeignKey"));
suite.addTest(new ForeignKeyTestSuite("testJoinTableForeignKeys"));
suite.addTest(new ForeignKeyTestSuite("testMapKeyForeignKey"));
suite.addTest(new ForeignKeyTestSuite("testManyToOneForeignKey"));
suite.addTest(new ForeignKeyTestSuite("testElementCollectionForeignKeys"));
suite.addTest(new ForeignKeyTestSuite("testReadAndWriteDDLObjects"));
return suite;
}
/**
* Tests an inheritance primary key foreign key setting.
*/
public void testInheritancePrimaryKeyForeignKey() {
ClassDescriptor sprinterDescriptor = getPersistenceUnitServerSession().getDescriptor(Sprinter.class);
DatabaseTable table = sprinterDescriptor.getTable("JPA21_DDL_SPRINTER");
assertForeignKeyConstraint("Sprinter_Foreign_Key", "FOREIGN KEY (SPRINTER_ID) REFERENCES JPA21_DDL_RUNNER (ID)", table);
}
/**
* Tests a collection table foreign key setting.
*/
public void testCollectionTableForeignKey() {
ClassDescriptor runnerDescriptor = getPersistenceUnitServerSession().getDescriptor(Runner.class);
DirectCollectionMapping mapping = (DirectCollectionMapping) runnerDescriptor.getMappingForAttributeName("personalBests");
DatabaseTable table = mapping.getReferenceTable();
assertForeignKeyConstraint("Runner_PBS_Foreign_Key", "FOREIGN KEY (RUNNER_ID) REFERENCES JPA21_DDL_RUNNER (ID)", table);
}
/**
* Tests a join table foreign key settings.
*/
public void testJoinTableForeignKeys() {
ClassDescriptor runnerDescriptor = getPersistenceUnitServerSession().getDescriptor(Runner.class);
ManyToManyMapping mapping = (ManyToManyMapping) runnerDescriptor.getMappingForAttributeName("races");
DatabaseTable table = mapping.getRelationTable();
assertForeignKeyConstraint("Runners_Races_Foreign_Key", "FOREIGN KEY (RUNNER_ID) REFERENCES JPA21_DDL_RUNNER (ID)", table);
assertForeignKeyConstraint("Runners_Races_Inverse_Foreign_Key", "FOREIGN KEY (RACE_ID) REFERENCES JPA21_DDL_RACE (ID)", table);
}
/**
* Tests a map key foreign key setting.
*/
public void testMapKeyForeignKey() {
ClassDescriptor runnerDescriptor = getPersistenceUnitServerSession().getDescriptor(Runner.class);
OneToManyMapping mapping = (OneToManyMapping) runnerDescriptor.getMappingForAttributeName("shoes");
OneToOneMapping keyMapping = (OneToOneMapping) ((MappedKeyMapContainerPolicy) mapping.getContainerPolicy()).getKeyMapping();
DatabaseTable table = keyMapping.getForeignKeyFields().get(0).getTable();
assertForeignKeyConstraint("Runner_ShoeTag_Foreign_Key", "FOREIGN KEY (TAG_ID) REFERENCES JPA21_DDL_SHOE_TAG (ID)", table);
}
/**
* Tests a many to one foreign key setting.
*/
public void testManyToOneForeignKey() {
ClassDescriptor shoeDescriptor = getPersistenceUnitServerSession().getDescriptor(Shoe.class);
OneToOneMapping mapping = (OneToOneMapping) shoeDescriptor.getMappingForAttributeName("runner");
DatabaseTable table = mapping.getForeignKeyFields().get(0).getTable();
assertForeignKeyConstraint("Shoes_Runner_Foreign_Key", "FOREIGN KEY (RUNNER_ID) REFERENCES JPA21_DDL_RUNNER (ID)", table);
ClassDescriptor organizerDescriptor = getPersistenceUnitServerSession().getDescriptor(Organizer.class);
mapping = (OneToOneMapping) organizerDescriptor.getMappingForAttributeName("race");
table = mapping.getForeignKeyFields().get(0).getTable();
assertForeignKeyConstraint("Organizer_Race_Foreign_Key", "FOREIGN KEY (RACE_ID) REFERENCES JPA21_DDL_RACE (ID)", table);
}
/**
* Tests an element collection foreign key settings.
*/
public void testElementCollectionForeignKeys() {
ClassDescriptor runnerDescriptor = getPersistenceUnitServerSession().getDescriptor(Runner.class);
DirectMapMapping mapping = (DirectMapMapping) runnerDescriptor.getMappingForAttributeName("endorsements");
OneToOneMapping keyMapping = (OneToOneMapping) ((MappedKeyMapContainerPolicy) mapping.getContainerPolicy()).getKeyMapping();
DatabaseTable table = mapping.getReferenceTable();
assertForeignKeyConstraint("Endorsements_Foreign_Key", "FOREIGN KEY (ATHLETE_ID) REFERENCES JPA21_DDL_RUNNER (ID)", table);
table = keyMapping.getForeignKeyFields().get(0).getTable();
assertForeignKeyConstraint("Endorsements_Key_Foreign_Key", "FOREIGN KEY (ENDORSER_ID) REFERENCES JPA_DDL_ENDORSER (ID)", table);
mapping = (DirectMapMapping) runnerDescriptor.getMappingForAttributeName("accomplishments");
table = mapping.getReferenceTable();
assertForeignKeyConstraint("Accomplistments_Foreign_Key", "FOREIGN KEY (ATHLETE_ID) REFERENCES JPA21_DDL_RUNNER (ID)", table);
}
/**
* Test copied from Converter test suite. Will write and read the objects
* back and at the same time test their converters as well.
*/
public void testReadAndWriteDDLObjects() {
EntityManager em = createEntityManager();
try {
beginTransaction(em);
Runner runner = new Runner();
runner.setAge(53);
runner.setIsFemale();
runner.setFirstName("Doris");
runner.setLastName("Day");
runner.addPersonalBest("10 KM", "47:34");
runner.addPersonalBest("5", "26:41");
runner.addAccomplishment("Ran 100KM without stopping", new Date(System.currentTimeMillis()));
RunnerInfo runnerInfo = new RunnerInfo();
runnerInfo.setHealth(Health.H);
runnerInfo.setLevel(Level.A);
RunnerStatus runnerStatus = new RunnerStatus();
runnerStatus.setRunningStatus(RunningStatus.D);
runnerInfo.setStatus(runnerStatus);
runner.setInfo(runnerInfo);
Coach coach = new Coach();
runner.addCoach(coach);
Race race = new Race();
race.setName("The Ultimate Marathon");
race.addRunner(runner);
Organizer organizer = new Organizer();
organizer.setName("Joe Organ");
organizer.setRace(race);
Responsibility responsibility = new Responsibility();
responsibility.setUniqueIdentifier(new Long(System.currentTimeMillis()));
responsibility.setDescription("Raise funds");
race.addOrganizer(organizer, responsibility);
em.persist(race);
em.persist(organizer);
em.persist(runner);
em.persist(coach);
commitTransaction(em);
// Clear the cache
em.clear();
clearCache();
Runner runnerRefreshed = em.find(Runner.class, runner.getId());
assertTrue("The age conversion did not work.", runnerRefreshed.getAge() == 52);
assertTrue("The embeddable health conversion did not work.", runnerRefreshed.getInfo().getHealth().equals(Health.HEALTHY));
assertTrue("The embeddable level conversion did not work.", runnerRefreshed.getInfo().getLevel().equals(Level.AMATEUR));
assertTrue("The nested embeddable running status conversion did not work.", runnerRefreshed.getInfo().getStatus().getRunningStatus().equals(RunningStatus.DOWN_TIME));
assertTrue("The number of personal bests for this runner is incorrect.", runnerRefreshed.getPersonalBests().size() == 2);
assertTrue("Distance (map key) conversion did not work.", runnerRefreshed.getPersonalBests().keySet().contains("10K"));
assertTrue("Distance (map key) conversion did not work.", runnerRefreshed.getPersonalBests().keySet().contains("5K"));
assertTrue("Time (map value) conversion did not work.", runnerRefreshed.getPersonalBests().values().contains("47:34.0"));
assertTrue("Time (map value) conversion did not work.", runnerRefreshed.getPersonalBests().values().contains("26:41.0"));
Race raceRefreshed = em.find(Race.class, race.getId());
Map<Responsibility, Organizer> organizers = raceRefreshed.getOrganizers();
assertFalse("No race organizers returned.", organizers.isEmpty());
assertTrue("More than one race organizer returned.", organizers.size() == 1);
Responsibility resp = organizers.keySet().iterator().next();
assertTrue("Responsibility was not uppercased by the converter", resp.getDescription().equals("RAISE FUNDS"));
for (String accomplishment : runnerRefreshed.getAccomplishments().keySet()) {
assertTrue("Accomplishment (map key) conversion did not work.", accomplishment.endsWith("!!!"));
}
} catch (RuntimeException e) {
if (isTransactionActive(em)){
rollbackTransaction(em);
}
throw e;
} finally {
closeEntityManager(em);
}
}
}