adding batch-fetch and database-partitioning examples
diff --git a/batch-fetch/.classpath b/batch-fetch/.classpath
new file mode 100644
index 0000000..4e2db7c
--- /dev/null
+++ b/batch-fetch/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/EclipseLink 1.2">
+ <attributes>
+ <attribute name="owner.project.facets" value="jpt.jpa;#system#"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Oracle JDBC"/>
+ <classpathentry kind="output" path="classes"/>
+</classpath>
diff --git a/batch-fetch/.project b/batch-fetch/.project
new file mode 100644
index 0000000..9c634b1
--- /dev/null
+++ b/batch-fetch/.project
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.persistence.example.jpa.batch-fetch</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+ <nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+ </natures>
+</projectDescription>
diff --git a/batch-fetch/batch-fetch.zip b/batch-fetch/batch-fetch.zip
new file mode 100644
index 0000000..66f48f3
--- /dev/null
+++ b/batch-fetch/batch-fetch.zip
Binary files differ
diff --git a/batch-fetch/build.xml b/batch-fetch/build.xml
new file mode 100644
index 0000000..da9ad22
--- /dev/null
+++ b/batch-fetch/build.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project basedir="." default="build" name="org.eclipse.persistence.example.jpa.batch-fetch">
+ <property environment="env"/>
+ <property name="JDBC_LIB" value="./ojdbc6.jar"/>
+ <property name="JPA_LIB" value="./persistence.jar"/>
+ <property name="ECLIPSELINK_LIB" value="./eclipselink.jar"/>
+ <property name="AGENT" value="-javaagent:${ECLIPSELINK_LIB}"/>
+ <property name="debuglevel" value="source,lines,vars"/>
+ <path id="example.classpath">
+ <pathelement location="classes"/>
+ <pathelement location="${JDBC_LIB}"/>
+ <pathelement location="${JPA_LIB}"/>
+ <pathelement location="${ECLIPSELINK_LIB}"/>
+ </path>
+ <target name="init" depends="clean">
+ <mkdir dir="classes"/>
+ </target>
+ <target name="clean">
+ <delete dir="classes"/>
+ </target>
+
+ <target depends="init" name="build">
+ <echo message="${ant.project.name}: ${ant.file}"/>
+ <javac debug="true" debuglevel="${debuglevel}" destdir="classes">
+ <src path="src"/>
+ <exclude name="**/.svn/**"/>
+ <classpath refid="example.classpath"/>
+ </javac>
+ <copy file="src/META-INF/persistence.xml" todir="classes/META-INF"/>
+ </target>
+
+ <target name="populate" depends="build">
+ <java classname="example.Populate"
+ fork="true">
+ <jvmarg value="${AGENT}"/>
+ <classpath refid="example.classpath"/>
+ </java>
+ </target>
+
+ <target name="queries" depends="build">
+ <java classname="example.Queries"
+ maxmemory="512m"
+ fork="true">
+ <jvmarg value="${AGENT}"/>
+ <classpath refid="example.classpath"/>
+ </java>
+ </target>
+</project>
diff --git a/batch-fetch/src/META-INF/persistence.xml b/batch-fetch/src/META-INF/persistence.xml
new file mode 100644
index 0000000..5bef3b8
--- /dev/null
+++ b/batch-fetch/src/META-INF/persistence.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
+ version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
+ <persistence-unit name="employee" transaction-type="RESOURCE_LOCAL">
+ <class>model.SmallProject</class>
+ <class>model.Project</class>
+ <class>model.PhoneNumber</class>
+ <class>model.LargeProject</class>
+ <class>model.EmploymentPeriod</class>
+ <class>model.Employee</class>
+ <class>model.Address</class>
+ <class>model.EmailAddress</class>
+ <class>model.JobTitle</class>
+ <class>model.Degree</class>
+ <properties>
+ <!-- Default database login using Oracle for EclipseLink's internal connection pool,
+ change this to access your own database. -->
+ <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.OracleDriver" />
+ <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:orcl" />
+ <property name="javax.persistence.jdbc.user" value="scott" />
+ <property name="javax.persistence.jdbc.password" value="tiger" />
+
+ <!-- The database platform is auto-detected by default,
+ if you want to set a specific platform this can be set. -->
+ <!-- property name=""eclipselink.target-database" value="Oracle" / -->
+
+ <!-- Optimize database writes to use batching. -->
+ <!-- property name="eclipselink.jdbc.batch-writing" value="JDBC" / -->
+
+ <!-- Avoids flush being triggered before every query execution. -->
+ <property name="eclipselink.persistence-context.flush-mode" value="COMMIT" />
+
+ <!-- Configure connection pool. -->
+ <property name="eclipselink.jdbc.connections.initial" value="1" />
+ <property name="eclipselink.jdbc.connections.min" value="64" />
+ <property name="eclipselink.jdbc.connections.max" value="64" />
+
+ <!-- Enabled statement caching, this is only required when using internal connection pooling,
+ when using a DataSource, statement caching must be configured in the DataSource. -->
+ <property name="eclipselink.jdbc.cache-statements" value="true" />
+
+ <!-- In JSE no server platform is used, if you wish to use this example is a JEE server with JTA,
+ then you need to set this. -->
+ <!-- property name="eclipselink.target-server" value="WebLogic" / -->
+
+ <!-- Configure cache size. -->
+ <property name="eclipselink.cache.size.default" value="1000" />
+ <!-- If desired, this option would disable caching. -->
+ <!-- property name="eclipselink.cache.shared.default" value="false" / -->
+
+ <!-- If desired, this option would force a JDBC connection to be held for the duration of an EntityManager,
+ instead of returned to the pool in between queries/transactions. -->
+ <!-- property name="eclipselink.jdbc.exclusive-connection.mode" value="Always" / -->
+
+ <!-- Configure database to be created on startup if not already existing. -->
+ <!-- property name="eclipselink.ddl-generation" value="create-tables" / -->
+ <!-- To drop and replace existing schema this can be used. -->
+ <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
+
+ <!-- Configure simple SQL logging for demonstration. -->
+ <!-- property name="eclipselink.logging.level" value="FINE" / -->
+ <property name="eclipselink.logging.thread" value="false" />
+ <property name="eclipselink.logging.session" value="false" />
+ <property name="eclipselink.logging.exceptions" value="false" />
+ <property name="eclipselink.logging.timestamp" value="false" />
+ </properties>
+ </persistence-unit>
+</persistence>
diff --git a/batch-fetch/src/example/Populate.java b/batch-fetch/src/example/Populate.java
new file mode 100644
index 0000000..7249d1e
--- /dev/null
+++ b/batch-fetch/src/example/Populate.java
@@ -0,0 +1,642 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ ******************************************************************************/
+package example;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import model.*;
+
+/**
+ * This example populates the database with example instances using JPA.
+ */
+public class Populate {
+
+ public static void main(String[] args) {
+ EntityManagerFactory emf = Persistence.createEntityManagerFactory("employee");
+ populate(emf);
+ emf.close();
+ }
+
+ public static void populate(EntityManagerFactory emf) {
+ EntityManager em = emf.createEntityManager();
+ em.getTransaction().begin();
+ population = new Populate();
+ Populate.population.persistAll(em);
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ public static Populate population = new Populate();
+
+ public Employee[] employees = { basicEmployeeExample1(), basicEmployeeExample2(), basicEmployeeExample3(), basicEmployeeExample4(), basicEmployeeExample5(), basicEmployeeExample6(),
+ basicEmployeeExample7(), basicEmployeeExample8(), basicEmployeeExample9(), basicEmployeeExample10(), basicEmployeeExample11(), basicEmployeeExample12() };
+
+ private SmallProject[] smallProjects = { basicSmallProjectExample1(), basicSmallProjectExample2(), basicSmallProjectExample3(), basicSmallProjectExample4(), basicSmallProjectExample5(),
+ basicSmallProjectExample7(), basicSmallProjectExample8(), basicSmallProjectExample9(), basicSmallProjectExample10() };
+
+ private LargeProject[] largeProjects = { basicLargeProjectExample1(), basicLargeProjectExample2(), basicLargeProjectExample3(), basicLargeProjectExample4(), basicLargeProjectExample5() };
+
+ private JobTitle[] jobTitles = { new JobTitle("CEO"), new JobTitle("VP"), new JobTitle("Manager"), new JobTitle("Developer"), new JobTitle("Admin") };
+
+ private Populate() {
+
+ // Setup management hierarchy
+ addManagedEmployees(0, new int[] { 2, 3, 4 });
+ setJobTitle(0, 2);
+ addManagedEmployees(1, new int[] { 5, 0 });
+ setJobTitle(1, 2);
+ addManagedEmployees(2, new int[] {});
+ setJobTitle(0, 3);
+ addManagedEmployees(3, new int[] {});
+ setJobTitle(0, 3);
+ addManagedEmployees(4, new int[] {});
+ setJobTitle(0, 3);
+ addManagedEmployees(5, new int[] {});
+ setJobTitle(5, 4);
+ addManagedEmployees(6, new int[] {});
+ setJobTitle(6, 4);
+ addManagedEmployees(7, new int[] {});
+ setJobTitle(7, 1);
+ addManagedEmployees(8, new int[] {});
+ setJobTitle(8, 4);
+ addManagedEmployees(9, new int[] { 7, 8, 10, 11 });
+ setJobTitle(9, 0);
+ addManagedEmployees(10, new int[] { 6 });
+ setJobTitle(10, 1);
+ addManagedEmployees(11, new int[] { 1 });
+ setJobTitle(11, 1);
+
+ // Setup Employee-Project associations
+ addProjects(0, new int[] { 0, 1, 2 }, new int[] {});
+ addProjects(1, new int[] { 3, 4, 0 }, new int[] {});
+ addProjects(2, new int[] { 3 }, new int[] { 3, 4 });
+ addProjects(4, new int[] { 3, 1 }, new int[] { 2, 4 });
+ addProjects(5, new int[] {}, new int[] { 1 });
+ addProjects(6, new int[] {}, new int[] { 1 });
+
+ // Setup LargeProject leads
+ this.largeProjects[0].setTeamLeader(this.employees[1]);
+ this.largeProjects[3].setTeamLeader(this.employees[2]);
+ this.largeProjects[4].setTeamLeader(this.employees[2]);
+ }
+
+ public Employee basicEmployeeExample1() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Bob");
+ employee.setLastName("Smith");
+ employee.setGender(Gender.Male);
+ employee.setSalary(35000);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(1996, 0, 1);
+ employmentPeriod.setStartDate(1993, 0, 1);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Toronto");
+ address.setPostalCode("L5J2B5");
+ address.setProvince("ONT");
+ address.setStreet("1450 Acme Cr., Suite 4");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addResponsibility("Water the office plants.");
+ employee.addResponsibility("Maintain the kitchen facilities.");
+ employee.addPhoneNumber("Work", "613", "5558812");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample10() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Jill");
+ employee.setLastName("May");
+ employee.setGender(Gender.Female);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setStartDate(1991, 10, 11);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Calgary");
+ address.setPostalCode("J5J2B5");
+ address.setProvince("AB");
+ address.setStreet("1111 Mooseland Rd.");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.setSalary(56232);
+ employee.addPhoneNumber("Work", "613", "5558812");
+ employee.addPhoneNumber("Work Fax", "613", "5555943");
+ employee.addEmailAddress("Work", "jill.may@acme.com");
+ employee.addEmailAddress("Mobile", "jill.lewis.may@sprint.com");
+ employee.addDegree("Bachelor Computer Science");
+ employee.addDegree("Masters Computer Science");
+ employee.addDegree("PHD Computer Science");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample11() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Sarah-Lou");
+ employee.setLastName("Smitty");
+ employee.setGender(Gender.Female);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(1996, 0, 1);
+ employmentPeriod.setStartDate(1993, 0, 1);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Arnprior");
+ address.setPostalCode("W1A2B5");
+ address.setProvince("ONT");
+ address.setStreet("1 Hawthorne Drive");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.setSalary(75000);
+ employee.addPhoneNumber("Work Fax", "613", "5555943");
+ employee.addPhoneNumber("Home", "613", "5551234");
+ employee.addPhoneNumber("Cellular", "416", "5551111");
+ employee.addEmailAddress("Home", "sarah-lou.smitty@rogers.com");
+ employee.addDegree("Bachelor Computer Science");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample12() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Jim-Bob");
+ employee.setLastName("Jefferson");
+ employee.setGender(Gender.Male);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(2001, 11, 31);
+ employmentPeriod.setStartDate(1995, 0, 12);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Yellowknife");
+ address.setPostalCode("Y5J2N5");
+ address.setProvince("YK");
+ address.setStreet("1112 Gold Rush Rd.");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.setSalary(50000);
+ employee.addPhoneNumber("Home", "613", "5551234");
+ employee.addPhoneNumber("Cellular", "416", "5551111");
+ employee.addEmailAddress("Home", "jim-bob@jim-bob.com");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample2() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("John");
+ employee.setLastName("Way");
+ employee.setGender(Gender.Male);
+ employee.setSalary(53000);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setStartDate(1991, 10, 11);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Ottawa");
+ address.setPostalCode("K5J2B5");
+ address.setProvince("ONT");
+ address.setStreet("12 Merivale Rd., Suite 5");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addResponsibility("Hire people when more people are required.");
+ employee.addResponsibility("Lay off employees when less people are required.");
+ employee.addPhoneNumber("Work", "613", "5558812");
+ employee.addPhoneNumber("ISDN", "905", "5553691");
+ employee.addEmailAddress("Work", "john.way@acme.com");
+ employee.addDegree("Bachelor Computer Science");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample3() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Charles");
+ employee.setLastName("Chanley");
+ employee.setGender(Gender.Male);
+ employee.setSalary(43000);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(2001, 11, 31);
+ employmentPeriod.setStartDate(1995, 0, 1);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Montreal");
+ address.setPostalCode("Q2S5Z5");
+ address.setProvince("QUE");
+ address.setStreet("1 Canadien Place");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addResponsibility("Perform code reviews as required.");
+ employee.addPhoneNumber("Pager", "976", "5556666");
+ employee.addPhoneNumber("ISDN", "905", "5553691");
+ employee.addEmailAddress("Work", "charles.chanley@acme.com");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample4() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Emanual");
+ employee.setLastName("Smith");
+ employee.setGender(Gender.Male);
+ employee.setSalary(49631);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(2001, 11, 31);
+ employmentPeriod.setStartDate(1995, 0, 1);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Vancouver");
+ address.setPostalCode("N5J2N5");
+ address.setProvince("BC");
+ address.setStreet("20 Mountain Blvd., Floor 53, Suite 6");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addResponsibility("Have to fix the Database problem.");
+ employee.addPhoneNumber("Work Fax", "613", "5555943");
+ employee.addPhoneNumber("Cellular", "416", "5551111");
+ employee.addPhoneNumber("Pager", "976", "5556666");
+ employee.addPhoneNumber("ISDN", "905", "5553691");
+ employee.addEmailAddress("Work", "emanual.smith@acme.com");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample5() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Sarah");
+ employee.setLastName("Way");
+ employee.setGender(Gender.Female);
+ employee.setSalary(87000);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(2001, 6, 31);
+ employmentPeriod.setStartDate(1995, 4, 1);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Prince Rupert");
+ address.setPostalCode("K3K5D5");
+ address.setProvince("BC");
+ address.setStreet("3254 Parkway Place");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addResponsibility("Write code documentation.");
+ employee.addPhoneNumber("Work", "613", "5558812");
+ employee.addPhoneNumber("ISDN", "905", "5553691");
+ employee.addPhoneNumber("Home", "613", "5551234");
+ employee.addEmailAddress("Work", "sarah.way@acme.com");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample6() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Marcus");
+ employee.setLastName("Saunders");
+ employee.setGender(Gender.Male);
+ employee.setSalary(54300);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(2001, 11, 31);
+ employmentPeriod.setStartDate(1995, 0, 12);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Perth");
+ address.setPostalCode("Y3Q2N9");
+ address.setProvince("ONT");
+ address.setStreet("234 Caledonia Lane");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addResponsibility("Write user specifications.");
+ employee.addPhoneNumber("ISDN", "905", "5553691");
+ employee.addPhoneNumber("Work", "613", "5558812");
+ employee.addEmailAddress("Work", "marcus.saunders@acme.com");
+ employee.addDegree("Bachelor Computer Science");
+ employee.addDegree("Masters Computer Science");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample7() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Nancy");
+ employee.setLastName("White");
+ employee.setGender(Gender.Female);
+ employee.setSalary(31000);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(1996, 0, 1);
+ employmentPeriod.setStartDate(1993, 0, 1);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Metcalfe");
+ address.setPostalCode("Y4F7V6");
+ address.setProvince("ONT");
+ address.setStreet("2 Anderson Rd.");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addPhoneNumber("Home", "613", "5551234");
+ employee.addEmailAddress("Work", "nancy.white@acme.com");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample8() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Fred");
+ employee.setLastName("Jones");
+ employee.setGender(Gender.Male);
+ employee.setSalary(500000);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setEndDate(2001, 11, 31);
+ employmentPeriod.setStartDate(1995, 0, 1);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Victoria");
+ address.setPostalCode("Z5J2N5");
+ address.setProvince("BC");
+ address.setStreet("382 Hyde Park Blvd.");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addPhoneNumber("Cellular", "416", "5551111");
+ employee.addPhoneNumber("ISDN", "905", "5553691");
+ employee.addEmailAddress("Work", "fred.jones@acme.com");
+ employee.addDegree("Bachelor Business");
+ employee.addDegree("Masters Business");
+
+ return employee;
+ }
+
+ public Employee basicEmployeeExample9() {
+ Employee employee = new Employee();
+
+ employee.setFirstName("Betty");
+ employee.setLastName("Jones");
+ employee.setGender(Gender.Female);
+ employee.setSalary(500001);
+
+ EmploymentPeriod employmentPeriod = new EmploymentPeriod();
+ employmentPeriod.setStartDate(2001, 11, 31);
+ employmentPeriod.setEndDate(1995, 0, 1);
+ employee.setPeriod(employmentPeriod);
+
+ Address address = new Address();
+ address.setCity("Smith Falls");
+ address.setPostalCode("C6C6C6");
+ address.setProvince("ONT");
+ address.setStreet("89 Chocolate Drive");
+ address.setCountry("Canada");
+ employee.setAddress(address);
+
+ employee.addPhoneNumber("Work", "613", "5558812");
+ employee.addPhoneNumber("ISDN", "905", "5553691");
+ employee.addEmailAddress("Work", "betty.jones@acme.com");
+ employee.addEmailAddress("Home", "betty.cleo.jones@rogers.com");
+ employee.addDegree("Bachelor Arts");
+ employee.addDegree("Masters Engineering");
+ employee.addDegree("PHD Philosophy");
+
+ return employee;
+ }
+
+ public LargeProject basicLargeProjectExample1() {
+ LargeProject largeProject = new LargeProject();
+
+ largeProject.setName("Sales Reporting");
+ largeProject.setDescription("A reporting application to report on the corporations database through TopLink.");
+ largeProject.setBudget((double) 5000);
+ largeProject.getMilestone().set(1991, 10, 11, 12, 0, 0);
+
+ return largeProject;
+ }
+
+ public LargeProject basicLargeProjectExample2() {
+ LargeProject largeProject = new LargeProject();
+
+ largeProject.setName("Light Reporter");
+ largeProject.setDescription("A lightweight application to report on the corporations database through TopLink.");
+ largeProject.setBudget(100.98);
+ largeProject.getMilestone().set(1999, 11, 25, 11, 40, 44);
+
+ return largeProject;
+ }
+
+ public LargeProject basicLargeProjectExample3() {
+ LargeProject largeProject = new LargeProject();
+
+ largeProject.setName("TOPEmployee Management");
+ largeProject.setDescription("A management application to report on the corporations database through TopLink.");
+ largeProject.setBudget(4000.98);
+ largeProject.getMilestone().set(1997, 10, 12, 1, 0, 0);
+
+ return largeProject;
+ }
+
+ public LargeProject basicLargeProjectExample4() {
+ LargeProject largeProject = new LargeProject();
+
+ largeProject.setName("Enterprise System");
+ largeProject.setDescription("A enterprise wide application to report on the corporations database through TopLink.");
+ largeProject.setBudget(40.98);
+ largeProject.getMilestone().set(1996, 8, 6, 6, 40, 44);
+
+ return largeProject;
+ }
+
+ public LargeProject basicLargeProjectExample5() {
+ LargeProject largeProject = new LargeProject();
+
+ largeProject.setName("Problem Reporting System");
+ largeProject.setDescription("A PRS application to report on the corporations database through TopLink.");
+ largeProject.setBudget(101.98);
+ largeProject.getMilestone().set(1997, 9, 6, 1, 40, 44);
+
+ return largeProject;
+ }
+
+ public SmallProject basicSmallProjectExample1() {
+ return new SmallProject("Enterprise", "A enterprise wide application to report on the corporations database through TopLink.");
+ }
+
+ public SmallProject basicSmallProjectExample10() {
+ return new SmallProject("Staff Query Tool", "A tool to help staff query various things.");
+ }
+
+ public SmallProject basicSmallProjectExample2() {
+ return new SmallProject("Sales Reporter", "A reporting application using JDK to report on the corporations database through TopLink.");
+ }
+
+ public SmallProject basicSmallProjectExample3() {
+ return new SmallProject("TOP-Employee Manager", "A management application to report on the corporations database through TopLink.");
+ }
+
+ public SmallProject basicSmallProjectExample4() {
+ return new SmallProject("Problem Reporter", "A PRS application to report on the corporations database through TopLink.");
+ }
+
+ public SmallProject basicSmallProjectExample5() {
+ return new SmallProject("Feather Reporter", "An extremely lightweight application to report on the corporations database through TopLink.");
+ }
+
+ public SmallProject basicSmallProjectExample6() {
+ return new SmallProject("Makework", "A makework project.");
+ }
+
+ public SmallProject basicSmallProjectExample7() {
+ return new SmallProject("Marketing Query Tool", "A tool to help marketing query various things.");
+ }
+
+ public SmallProject basicSmallProjectExample8() {
+ return new SmallProject("Shipping Query Tool", "A tool to help shipping query various things.");
+ }
+
+ public SmallProject basicSmallProjectExample9() {
+ return new SmallProject("Accounting Query Tool", "A tool to help accounting query various things.");
+ }
+
+ private void addManagedEmployees(int managerIndex, int[] employeeIndeces) {
+ Employee manager = this.employees[managerIndex];
+
+ if (manager.getManagedEmployees().isEmpty()) {
+ for (int index = 0; index < employeeIndeces.length; index++) {
+ manager.addManagedEmployee(this.employees[employeeIndeces[index]]);
+ }
+ }
+ }
+
+ private void setJobTitle(int employeeIndex, int jobIndex) {
+ Employee employee = this.employees[employeeIndex];
+
+ employee.setJobTitle(this.jobTitles[jobIndex]);
+ }
+
+ private void addProjects(int empIndex, int[] smallProjIndeces, int[] largeProjIndeces) {
+ Employee employee = this.employees[empIndex];
+
+ for (int index = 0; index < smallProjIndeces.length; index++) {
+ employee.addProject(this.smallProjects[smallProjIndeces[index]]);
+ }
+
+ for (int index = 0; index < largeProjIndeces.length; index++) {
+ employee.addProject(this.largeProjects[largeProjIndeces[index]]);
+ }
+ }
+
+ /**
+ * Register all of the population in the provided EntityManager to be
+ * persisted This method should only be called from within a test case. It
+ * asserts that the provided EntityManager is in a transaction and that the
+ * database tables are empty.
+ */
+ public void persistAll(EntityManager em) {
+ System.out.println("Persisting samples objects.");
+
+ assert(em.getTransaction().isActive());
+
+ // Verify that the database tables are empty
+ assertCount(em, Employee.class, 0);
+ assertCount(em, Address.class, 0);
+ assertCount(em, PhoneNumber.class, 0);
+ assertCount(em, Project.class, 0);
+ assertCount(em, JobTitle.class, 0);
+
+ for (int index = 0; index < this.jobTitles.length; index++) {
+ em.persist(this.jobTitles[index]);
+ }
+ for (int index = 0; index < this.employees.length; index++) {
+ em.persist(this.employees[index]);
+ }
+ for (int index = 0; index < this.smallProjects.length; index++) {
+ em.persist(this.smallProjects[index]);
+ }
+ for (int index = 0; index < this.largeProjects.length; index++) {
+ em.persist(this.largeProjects[index]);
+ }
+
+ System.out.println("Flushing to database.");
+ em.flush();
+
+ System.out.println("Verifying populate.");
+ verifyCounts(em);
+ }
+
+ public void verifyCounts(EntityManager em) {
+ assertCount(em, Employee.class, this.employees.length);
+ assertCount(em, Address.class, this.employees.length);
+ assertCount(em, Project.class, this.smallProjects.length + this.largeProjects.length);
+ assertCount(em, JobTitle.class, this.jobTitles.length);
+ }
+
+ /**
+ * Verify that the provided entity type has no rows in the database using a
+ * native ReportQuery.
+ *
+ * @param entityClass
+ * @param count
+ */
+ public void assertCount(EntityManager em, Class entityClass, int count) {
+ CriteriaBuilder cb = em.getCriteriaBuilder();
+ CriteriaQuery criteria = cb.createQuery();
+ Root entity = criteria.from(entityClass);
+ criteria.select(cb.count(entity));
+ Query query = em.createQuery(criteria);
+
+ Long dbCount = (Long)query.getSingleResult();
+ assert(count == dbCount.intValue());
+ }
+
+}
diff --git a/batch-fetch/src/example/Queries.java b/batch-fetch/src/example/Queries.java
new file mode 100644
index 0000000..5539adc
--- /dev/null
+++ b/batch-fetch/src/example/Queries.java
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ ******************************************************************************/
+package example;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.Query;
+
+import model.*;
+
+/**
+ * Simple query examples.
+ */
+public class Queries {
+
+ public static int REPEATS = 5;
+ public static int RUN_TIME = 60000; //1 minute.
+
+ /**
+ * Measure the performance of the run.
+ * Repeat the run REPEATS (5) times,
+ * and measure the number of execution in RUN_TIME (60s).
+ */
+ public static void executeRun(String name, Runnable runnable) {
+ System.out.println("Starting run: " + name);
+
+ List<Integer> results = new ArrayList<Integer>();
+ // Repeat the test and baseline for the number of repeats.
+ for (int index = 0; index < REPEATS; index++) {
+ long startTime, endTime;
+ int executions = 0;
+ System.gc();
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignore) {}
+ startTime = System.currentTimeMillis();
+ endTime = startTime;
+ // Count how many times the test can be invoked in the run time.
+ // This allows for the test run time to be easily changed.
+ while ((startTime + RUN_TIME) >= endTime) {
+ runnable.run();
+ executions++;
+ endTime = System.currentTimeMillis();
+ }
+ results.add(executions);
+ System.out.println("Done run: " + index + " for: " + name);
+ }
+
+ System.out.println("Completed run: " + name);
+
+ System.out.println("");
+ System.out.println(name + " Results");
+ System.out.println("Run repeats:" + REPEATS);
+ System.out.println("Run time:" + RUN_TIME + "ms");
+ System.out.println("Average result:" + averageResults(results));
+ System.out.println("Max result:" + maxResults(results));
+ System.out.println("Min result:" + minResults(results));
+ System.out.println("% standard deviation:" + standardDeviationResults(results));
+ System.out.println("");
+ System.out.println("");
+ }
+
+ /**
+ * Compute the max of the results.
+ */
+ public static int maxResults(List<Integer> times) {
+ int testMax = 0;
+ for (int index = 0; index < times.size(); index++) {
+ int time = (int)times.get(index);
+ if (time > testMax) {
+ testMax = time;
+ }
+ }
+ return testMax;
+ }
+
+ /**
+ * Compute the min of the results.
+ */
+ public static int minResults(List<Integer> times) {
+ int testMin = 0;
+ for (int index = 0; index < times.size(); index++) {
+ int time = (int)times.get(index);
+ if ((testMin == 0) || (time < testMin)) {
+ testMin = time;
+ }
+ }
+ return testMin;
+ }
+
+ /**
+ * Filter max and min from results.
+ */
+ public static List<Integer> filterMaxMinResults(List<Integer> times) {
+ List filteredTimes = new ArrayList(times);
+ if (filteredTimes.size() > 3) {
+ filteredTimes.remove((Integer)maxResults(times));
+ filteredTimes.remove((Integer)minResults(times));
+ }
+ return filteredTimes;
+ }
+
+ /**
+ * Compute the average of the results rejecting the min and max.
+ */
+ public static double averageResults(List<Integer> allTimes) {
+ // Compute the average reject the min and max to improve consistency.
+ List<Integer> times = filterMaxMinResults(allTimes);
+ double testAverage = 0;
+ for (int index = 0; index < times.size(); index++) {
+ int time = (int)times.get(index);
+ testAverage = testAverage + time;
+ }
+ testAverage = testAverage / times.size();
+ return testAverage;
+ }
+
+ /**
+ * Compute the standard deviation of the results rejecting the min and max.
+ */
+ public static double standardDeviationResults(List<Integer> allTimes) {
+ // Compute the average reject the min and max to improve consistency.
+ double testAverage = averageResults(allTimes);
+
+ // Compute the standard deviation reject the min and max to improve consistency.
+ List<Integer> times = filterMaxMinResults(allTimes);
+ double testStandardDeviation = 0;
+ for (int index = 0; index < times.size(); index++) {
+ int time = (int)times.get(index);
+ testStandardDeviation = testStandardDeviation + Math.pow(time - testAverage, 2);
+ }
+ testStandardDeviation = testStandardDeviation / times.size();
+ testStandardDeviation = Math.sqrt(testStandardDeviation);
+ // As percent of average
+ testStandardDeviation = (testStandardDeviation / testAverage) * 100;
+ return testStandardDeviation;
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ EntityManagerFactory emf = Persistence.createEntityManagerFactory("employee");
+ //for (int index = 0; index < 5000; index++) {
+ Populate.populate(emf);
+ //}
+ Queries queries = new Queries();
+ queries.clear(emf);
+ queries.runSimpleQuery("standardFindAllBySalary", emf);
+ queries.runSimpleQuery("simpleJoinFetchFindAllBySalary", emf);
+ queries.runSimpleQuery("simpleBatchJOINFetchFindAllBySalary", emf);
+ queries.runSimpleQuery("simpleBatchEXISTSFetchFindAllBySalary", emf);
+ queries.runSimpleQuery("simpleBatchINFetchFindAllBySalary", emf);
+
+ queries.runComplexQuery("standardFindAllBySalary", emf);
+ queries.runComplexQuery("joinFetchFindAllBySalary", emf);
+ queries.runComplexQuery("batchJOINFetchFindAllBySalary", emf);
+ queries.runComplexQuery("batchEXISTSFetchFindAllBySalary", emf);
+ queries.runComplexQuery("batchINFetchFindAllBySalary", emf);
+ emf.close();
+ }
+
+ public void runSimpleQuery(final String queryName, final EntityManagerFactory emf) {
+
+ executeRun(queryName, new Runnable() {
+ public void run() {
+ EntityManager em = emf.createEntityManager();
+ Query query = em.createNamedQuery(queryName);
+ query.setParameter("salary", 50000);
+ List<Employee> result = query.getResultList();
+ for (Employee employee : result) {
+ // Ensure every relationship is accessed.
+ String.valueOf(employee.getAddress());
+ employee.getPhoneNumbers().size();
+ }
+ em.close();
+ clear(emf);
+ }
+ });
+ }
+
+ public void runComplexQuery(final String queryName, final EntityManagerFactory emf) {
+
+ executeRun(queryName, new Runnable() {
+ public void run() {
+ EntityManager em = emf.createEntityManager();
+ Query query = em.createNamedQuery(queryName);
+ query.setParameter("salary", 50000);
+ List<Employee> result = query.getResultList();
+ for (Employee employee : result) {
+ // Ensure every relationship is accessed.
+ String.valueOf(employee.getAddress());
+ employee.getManagedEmployees().size();
+ employee.getDegrees().size();
+ String.valueOf(employee.getManager());
+ String.valueOf(employee.getJobTitle());
+ employee.getEmailAddresses().size();
+ employee.getPhoneNumbers().size();
+ employee.getProjects().size();
+ employee.getResponsibilities().size();
+ }
+ em.close();
+ clear(emf);
+ }
+ });
+ }
+
+ public void clear(EntityManagerFactory factory) {
+ factory.getCache().evictAll();
+ }
+}
diff --git a/batch-fetch/src/model/Address.java b/batch-fetch/src/model/Address.java
new file mode 100644
index 0000000..3799d9d
--- /dev/null
+++ b/batch-fetch/src/model/Address.java
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ * mbraeuer - annotated version
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+import javax.persistence.*;
+
+/**
+ * Simple Address class with Basic mappings.
+ * It uses a generated Id.
+ */
+@Entity
+@Table(name="BF_ADDRESS")
+public class Address implements Serializable {
+ @Id
+ @Column(name = "ADDRESS_ID")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private long id;
+ @Basic
+ private String city;
+ @Basic
+ private String country;
+ @Basic
+ private String province;
+ @Basic
+ @Column(name = "P_CODE")
+ private String postalCode;
+ @Basic
+ private String street;
+
+ public Address() {
+ }
+
+ public long getId() {
+ return this.id;
+ }
+
+ public void setId(long addressId) {
+ this.id = addressId;
+ }
+
+ public String getCity() {
+ return city;
+ }
+
+ public void setCity(String city) {
+ this.city = city;
+ }
+
+ public String getCountry() {
+ return country;
+ }
+
+ public void setCountry(String country) {
+ this.country = country;
+ }
+
+ public String getProvince() {
+ return province;
+ }
+
+ public void setProvince(String province) {
+ this.province = province;
+ }
+
+ public String getPostalCode() {
+ return this.postalCode;
+ }
+
+ public void setPostalCode(String postalCode) {
+ this.postalCode = postalCode;
+ }
+
+ public String getStreet() {
+ return street;
+ }
+
+ public void setStreet(String street) {
+ this.street = street;
+ }
+}
diff --git a/batch-fetch/src/model/Degree.java b/batch-fetch/src/model/Degree.java
new file mode 100644
index 0000000..61815ef
--- /dev/null
+++ b/batch-fetch/src/model/Degree.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * James Sutherland - initial example
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+import javax.persistence.*;
+
+/**
+ * Represents an employee's job title.
+ */
+@Entity
+@Table(name="BF_DEGREE")
+public class Degree implements Serializable {
+ @Id
+ @Column(name = "DEGREE_ID")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private long id;
+ @Basic
+ private String name;
+
+ public Degree() {
+ }
+
+ public Degree(String name) {
+ this.name = name;
+ }
+
+ public long getId() {
+ return this.id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+}
diff --git a/batch-fetch/src/model/EmailAddress.java b/batch-fetch/src/model/EmailAddress.java
new file mode 100644
index 0000000..a1e558a
--- /dev/null
+++ b/batch-fetch/src/model/EmailAddress.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * James Sutherland - initial example
+ ******************************************************************************/
+package model;
+
+import javax.persistence.Column;
+import javax.persistence.Embeddable;
+
+import org.eclipse.persistence.annotations.ChangeTracking;
+import org.eclipse.persistence.annotations.ChangeTrackingType;
+
+/**
+ * Represents the email address of an employee.
+ */
+@Embeddable
+// TODO, this is currently required to workaround an issue with weaving and ElementCollection mappings.
+@ChangeTracking(ChangeTrackingType.DEFERRED)
+public class EmailAddress {
+
+ @Column(name = "EMAIL_ADDRESS")
+ private String address;
+
+ public EmailAddress() {
+ }
+
+ public EmailAddress(String address) {
+ setAddress(address);
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+}
diff --git a/batch-fetch/src/model/Employee.java b/batch-fetch/src/model/Employee.java
new file mode 100644
index 0000000..31358d2
--- /dev/null
+++ b/batch-fetch/src/model/Employee.java
@@ -0,0 +1,387 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ * mbraeuer - annotated version, transformation
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.persistence.*;
+
+/**
+ * The Employee class demonstrates several JPA, JPA 2.0, and EclipseLink mapping features including:
+ * <ul>
+ * <li>Generated Id
+ * <li>Version locking
+ * <li>OneToOne relationships (dependent, and independent)
+ * <li>OneToOne relationship using JoinTable
+ * <li>ManyToMany relationship
+ * <li>OneToMany relationship (dependent, and independent)
+ * <li>Embedded relationship
+ * <li>ElementCollection relationships (Basic, and Embeddable) (JPA 2.0)
+ * <li>enums
+ * <li>OrderColumn (JPA 2.0)
+ * <li>MapKeyColumn (JPA 2.0)
+ * <li>orphanRemoval (JPA 2.0)
+ * </ul>
+ */
+@Entity
+@Table(name="BF_EMPLOYEE")
+@SecondaryTable(name = "BF_SALARY")
+@NamedQueries({
+ @NamedQuery(name="standardFindAllBySalary", query="Select e from Employee e where e.salary > :salary"),
+
+ @NamedQuery(name="joinFetchFindAllBySalary", query="Select e from Employee e "
+ + "left join fetch e.address left join fetch e.managedEmployees "
+ + "left join fetch e.jobTitle left join fetch e.degrees "
+ + "left join fetch e.manager left join fetch e.emailAddresses "
+ + "left join fetch e.projects left join fetch e.phoneNumbers "
+ + "left join fetch e.responsibilities "
+ + "where e.salary > :salary"),
+
+ @NamedQuery(name="batchJOINFetchFindAllBySalary", query="Select e from Employee e where e.salary > :salary",
+ hints={ @QueryHint(name="eclipselink.batch", value="e.address"),
+ @QueryHint(name="eclipselink.batch", value="e.jobTitle"),
+ @QueryHint(name="eclipselink.batch", value="e.manager"),
+ @QueryHint(name="eclipselink.batch", value="e.projects"),
+ @QueryHint(name="eclipselink.batch", value="e.responsibilities"),
+ @QueryHint(name="eclipselink.batch", value="e.managedEmployees"),
+ @QueryHint(name="eclipselink.batch", value="e.degrees"),
+ @QueryHint(name="eclipselink.batch", value="e.phoneNumbers"),
+ @QueryHint(name="eclipselink.batch", value="e.emailAddresses")}),
+
+ @NamedQuery(name="batchEXISTSFetchFindAllBySalary", query="Select e from Employee e where e.salary > :salary",
+ hints={ @QueryHint(name="eclipselink.batch.type", value="EXISTS"),
+ @QueryHint(name="eclipselink.batch", value="e.address"),
+ @QueryHint(name="eclipselink.batch", value="e.jobTitle"),
+ @QueryHint(name="eclipselink.batch", value="e.manager"),
+ @QueryHint(name="eclipselink.batch", value="e.projects"),
+ @QueryHint(name="eclipselink.batch", value="e.responsibilities"),
+ @QueryHint(name="eclipselink.batch", value="e.managedEmployees"),
+ @QueryHint(name="eclipselink.batch", value="e.degrees"),
+ @QueryHint(name="eclipselink.batch", value="e.phoneNumbers"),
+ @QueryHint(name="eclipselink.batch", value="e.emailAddresses")}),
+
+ @NamedQuery(name="batchINFetchFindAllBySalary", query="Select e from Employee e where e.salary > :salary",
+ hints={ @QueryHint(name="eclipselink.batch.type", value="IN"),
+ @QueryHint(name="eclipselink.batch", value="e.address"),
+ @QueryHint(name="eclipselink.batch", value="e.jobTitle"),
+ @QueryHint(name="eclipselink.batch", value="e.manager"),
+ @QueryHint(name="eclipselink.batch", value="e.projects"),
+ @QueryHint(name="eclipselink.batch", value="e.responsibilities"),
+ @QueryHint(name="eclipselink.batch", value="e.managedEmployees"),
+ @QueryHint(name="eclipselink.batch", value="e.degrees"),
+ @QueryHint(name="eclipselink.batch", value="e.phoneNumbers"),
+ @QueryHint(name="eclipselink.batch", value="e.emailAddresses")}),
+
+ @NamedQuery(name="simpleJoinFetchFindAllBySalary", query="Select e from Employee e "
+ + "left join fetch e.address left join fetch e.phoneNumbers "
+ + "where e.salary > :salary"),
+
+ @NamedQuery(name="simpleBatchJOINFetchFindAllBySalary", query="Select e from Employee e where e.salary > :salary",
+ hints={ @QueryHint(name="eclipselink.batch.type", value="JOIN"),
+ @QueryHint(name="eclipselink.batch", value="e.address"),
+ @QueryHint(name="eclipselink.batch", value="e.phoneNumbers")}),
+
+ @NamedQuery(name="simpleBatchEXISTSFetchFindAllBySalary", query="Select e from Employee e where e.salary > :salary",
+ hints={ @QueryHint(name="eclipselink.batch.type", value="EXISTS"),
+ @QueryHint(name="eclipselink.batch", value="e.address"),
+ @QueryHint(name="eclipselink.batch", value="e.phoneNumbers")}),
+
+ @NamedQuery(name="simpleBatchINFetchFindAllBySalary", query="Select e from Employee e where e.salary > :salary",
+ hints={ @QueryHint(name="eclipselink.batch.type", value="IN"),
+ @QueryHint(name="eclipselink.batch", value="e.address"),
+ @QueryHint(name="eclipselink.batch", value="e.phoneNumbers")})
+})
+public class Employee implements Serializable {
+ @Id
+ @Column(name = "EMP_ID")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private long id;
+
+ @Version
+ private long version;
+
+ @Column(name = "F_NAME")
+ private String firstName;
+
+ @Column(name = "L_NAME")
+ private String lastName;
+
+ @Basic
+ @Column(name = "GENDER")
+ @Enumerated(EnumType.STRING)
+ private Gender gender = Gender.Male;
+
+ @Column(table = "BF_SALARY")
+ private double salary;
+
+ @Embedded
+ @AttributeOverrides( {
+ @AttributeOverride(name = "startDate", column = @Column(name = "START_DATE")),
+ @AttributeOverride(name = "endDate", column = @Column(name = "END_DATE")) })
+ private EmploymentPeriod period;
+
+ @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
+ @JoinColumn(name = "ADDR_ID")
+ private Address address;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinTable(name = "BF_EMP_JOB", joinColumns = @JoinColumn(name = "EMP_ID"), inverseJoinColumns = @JoinColumn(name = "TITLE_ID"))
+ private JobTitle jobTitle;
+
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "MANAGER_ID")
+ private Employee manager;
+
+ @OneToMany(mappedBy = "manager")
+ private List<Employee> managedEmployees = new ArrayList<Employee>();
+
+ @OneToMany(mappedBy = "owner", cascade = CascadeType.ALL, orphanRemoval = true)
+ private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>();
+
+ @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
+ @JoinColumn(name="EMP_ID")
+ private List<Degree> degrees = new ArrayList<Degree>();
+
+ @ManyToMany
+ @JoinTable(name = "BF_PROJ_EMP", joinColumns = @JoinColumn(name = "EMP_ID"), inverseJoinColumns = @JoinColumn(name = "PROJ_ID"))
+ private List<Project> projects = new ArrayList<Project>();
+
+ @ElementCollection
+ @CollectionTable(name = "BF_RESPONS", joinColumns = @JoinColumn(name = "EMP_ID"))
+ @Column(name = "RESPONSIBILITY")
+ @OrderColumn(name = "PRIORITY")
+ private List<String> responsibilities = new ArrayList<String>();
+
+ @ElementCollection
+ @CollectionTable(name = "BF_EMAIL", joinColumns = @JoinColumn(name = "EMP_ID"))
+ @Column(name = "EMAIL_ADDRESS")
+ @MapKeyColumn(name = "EMAIL_TYPE")
+ private Map<String, EmailAddress> emailAddresses = new HashMap<String, EmailAddress>();
+
+ public Employee() {
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long empId) {
+ this.id = empId;
+ }
+
+ public String getFirstName() {
+ return firstName;
+ }
+
+ public void setFirstName(String fName) {
+ this.firstName = fName;
+ }
+
+ public Gender getGender() {
+ return this.gender;
+ }
+
+ public void setGender(Gender gender) {
+ this.gender = gender;
+ }
+
+ public String getLastName() {
+ return lastName;
+ }
+
+ public void setLastName(String lName) {
+ this.lastName = lName;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public List<Degree> getDegrees() {
+ return degrees;
+ }
+
+ public void setDegrees(List<Degree> degrees) {
+ this.degrees = degrees;
+ }
+
+ public Degree addDegree(String degree) {
+ return addDegree(new Degree(degree));
+ }
+
+ public Degree addDegree(Degree degree) {
+ getDegrees().add(degree);
+ return degree;
+ }
+
+ public Degree removeDegree(Degree degree) {
+ getDegrees().remove(degree);
+ return degree;
+ }
+
+ public List<Project> getProjects() {
+ return projects;
+ }
+
+ public void setProjects(List<Project> projectList) {
+ this.projects = projectList;
+ }
+
+ public Project addProject(Project project) {
+ getProjects().add(project);
+ return project;
+ }
+
+ public Project removeProject(Project project) {
+ getProjects().remove(project);
+ return project;
+ }
+
+ public Employee getManager() {
+ return manager;
+ }
+
+ public void setManager(Employee employee) {
+ this.manager = employee;
+ }
+
+ public List<Employee> getManagedEmployees() {
+ return this.managedEmployees;
+ }
+
+ public void setManagedEmployees(List<Employee> employeeList) {
+ this.managedEmployees = employeeList;
+ }
+
+ public Employee addManagedEmployee(Employee employee) {
+ getManagedEmployees().add(employee);
+ employee.setManager(this);
+ return employee;
+ }
+
+ public Employee removeManagedEmployee(Employee employee) {
+ getManagedEmployees().remove(employee);
+ employee.setManager(null);
+ return employee;
+ }
+
+ public List<PhoneNumber> getPhoneNumbers() {
+ return phoneNumbers;
+ }
+
+ public void setPhoneNumbers(List<PhoneNumber> phoneNumberList) {
+ this.phoneNumbers = phoneNumberList;
+ }
+
+ public PhoneNumber addPhoneNumber(PhoneNumber phoneNumber) {
+ getPhoneNumbers().add(phoneNumber);
+ phoneNumber.setOwner(this);
+ return phoneNumber;
+ }
+
+ public PhoneNumber addPhoneNumber(String type, String areaCode, String number) {
+ PhoneNumber phoneNumber = new PhoneNumber(type, areaCode, number);
+ return addPhoneNumber(phoneNumber);
+ }
+
+ public PhoneNumber removePhoneNumber(PhoneNumber phoneNumber) {
+ getPhoneNumbers().remove(phoneNumber);
+ phoneNumber.setOwner(null);
+ return phoneNumber;
+ }
+
+ public void setAddress(Address address) {
+ this.address = address;
+ }
+
+ public Address getAddress() {
+ return address;
+ }
+
+ public void setPeriod(EmploymentPeriod period) {
+ this.period = period;
+ }
+
+ public EmploymentPeriod getPeriod() {
+ return period;
+ }
+
+ public double getSalary() {
+ return salary;
+ }
+
+ public void setSalary(double salary) {
+ this.salary = salary;
+ }
+
+ public List<String> getResponsibilities() {
+ return this.responsibilities;
+ }
+
+ public void setResponsibilities(List<String> responsibilities) {
+ this.responsibilities = responsibilities;
+ }
+
+ public void addResponsibility(String responsibility) {
+ getResponsibilities().add(responsibility);
+ }
+
+ public void removeResponsibility(String responsibility) {
+ getResponsibilities().remove(responsibility);
+ }
+
+ public Map<String, EmailAddress> getEmailAddresses() {
+ return emailAddresses;
+ }
+
+ public void setEmailAddresses(Map<String, EmailAddress> emailAddresses) {
+ this.emailAddresses = emailAddresses;
+ }
+
+ public EmailAddress addEmailAddress(String type, String address) {
+ return addEmailAddress(type, new EmailAddress(address));
+ }
+
+ public EmailAddress addEmailAddress(String type, EmailAddress address) {
+ return getEmailAddresses().put(type, address);
+ }
+
+ public EmailAddress removeEmailAddress(String type) {
+ return getEmailAddresses().remove(type);
+ }
+
+ public EmailAddress getEmailAddress(String type) {
+ return getEmailAddresses().get(type);
+ }
+
+ public JobTitle getJobTitle() {
+ return jobTitle;
+ }
+
+ public void setJobTitle(JobTitle jobTitle) {
+ this.jobTitle = jobTitle;
+ }
+
+ public String toString() {
+ return "Employee(" + getId() + ": " + getLastName() + ", " + getFirstName() + ")";
+ }
+}
diff --git a/batch-fetch/src/model/EmploymentPeriod.java b/batch-fetch/src/model/EmploymentPeriod.java
new file mode 100644
index 0000000..71a8da9
--- /dev/null
+++ b/batch-fetch/src/model/EmploymentPeriod.java
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ * mbraeuer - annotated version
+ ******************************************************************************/
+package model;
+
+import java.util.Calendar;
+
+import javax.persistence.Embeddable;
+import javax.persistence.Temporal;
+import javax.persistence.TemporalType;
+
+/**
+ * Represents the period of time an employee has worked for the company. A null
+ * endDate indicates that the employee is current.
+ *
+ * @author djclarke
+ */
+@Embeddable
+public class EmploymentPeriod {
+
+ @Temporal(TemporalType.DATE)
+ private Calendar startDate;
+ @Temporal(TemporalType.DATE)
+ private Calendar endDate;
+
+ public Calendar getStartDate() {
+ return startDate;
+ }
+
+ public void setStartDate(Calendar startDate) {
+ this.startDate = startDate;
+ }
+
+ public void setStartDate(int year, int month, int day) {
+ Calendar date = Calendar.getInstance();
+ date.set(year, month + 1, day);
+ setStartDate(date);
+ }
+
+ public Calendar getEndDate() {
+ return endDate;
+ }
+
+ public void setEndDate(Calendar endDate) {
+ this.endDate = endDate;
+ }
+
+ public void setEndDate(int year, int month, int day) {
+ Calendar date = Calendar.getInstance();
+ date.set(year, month + 1, day);
+ setEndDate(date);
+ }
+}
diff --git a/batch-fetch/src/model/Gender.java b/batch-fetch/src/model/Gender.java
new file mode 100644
index 0000000..089ce5e
--- /dev/null
+++ b/batch-fetch/src/model/Gender.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ ******************************************************************************/
+package model;
+
+/**
+ * Represents an employee's gender.
+ */
+public enum Gender {
+ Female, Male
+}
diff --git a/batch-fetch/src/model/JobTitle.java b/batch-fetch/src/model/JobTitle.java
new file mode 100644
index 0000000..62c6e26
--- /dev/null
+++ b/batch-fetch/src/model/JobTitle.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * James Sutherland - initial example
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+import javax.persistence.*;
+
+/**
+ * Represents an employee's job title.
+ */
+@Entity
+@Table(name="BF_JOBTITLE")
+public class JobTitle implements Serializable {
+ @Id
+ @Column(name = "JOB_ID")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private long id;
+ @Basic
+ private String title;
+
+ public JobTitle() {
+ }
+
+ public JobTitle(String title) {
+ this.title = title;
+ }
+
+ public long getId() {
+ return this.id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+}
diff --git a/batch-fetch/src/model/LargeProject.java b/batch-fetch/src/model/LargeProject.java
new file mode 100644
index 0000000..91aabfc
--- /dev/null
+++ b/batch-fetch/src/model/LargeProject.java
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ * mbraeuer - annotated version
+ ******************************************************************************/
+package model;
+
+import java.util.Calendar;
+
+import javax.persistence.*;
+
+/**
+ * The LargeProject class demonstrates usage of JOINED inheritance.
+ */
+@Entity
+@Table(name = "BF_LPROJECT")
+@DiscriminatorValue("L")
+public class LargeProject extends Project {
+ @Basic
+ private double budget;
+ @Basic
+ @Temporal(TemporalType.TIMESTAMP)
+ private Calendar milestone = Calendar.getInstance();
+
+ public LargeProject() {
+ super();
+ }
+
+ public double getBudget() {
+ return this.budget;
+ }
+
+ public void setBudget(double budget) {
+ this.budget = budget;
+ }
+
+ public Calendar getMilestone() {
+ return milestone;
+ }
+
+ public void setMilestone(Calendar milestone) {
+ this.milestone = milestone;
+ }
+}
diff --git a/batch-fetch/src/model/PhoneNumber.java b/batch-fetch/src/model/PhoneNumber.java
new file mode 100644
index 0000000..ea56b20
--- /dev/null
+++ b/batch-fetch/src/model/PhoneNumber.java
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ * mbraeuer - annotated version
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+/**
+ * Represents the phone number an employee.
+ * This demonstrates the usage of a composite Id, and Id using a ManyToOne relationship.
+ */
+@Entity
+@Table(name = "BF_PHONE")
+@IdClass(PhoneNumber.ID.class)
+public class PhoneNumber implements Serializable {
+
+ @Id
+ @Column(updatable = false)
+ private String type;
+ @Basic
+ @Column(name = "AREA_CODE")
+ private String areaCode;
+ @Basic
+ @Column(name = "P_NUMBER")
+ private String number;
+ @Id
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "EMP_ID")
+ private Employee owner;
+
+ public PhoneNumber() {
+ }
+
+ public PhoneNumber(String type, String areaCode, String number) {
+ this();
+ setType(type);
+ setAreaCode(areaCode);
+ setNumber(number);
+ }
+
+ public String getAreaCode() {
+ return areaCode;
+ }
+
+ public void setAreaCode(String areaCode) {
+ this.areaCode = areaCode;
+ }
+
+ public String getNumber() {
+ return this.number;
+ }
+
+ public void setNumber(String pNumber) {
+ this.number = pNumber;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public Employee getOwner() {
+ return this.owner;
+ }
+
+ protected void setOwner(Employee employee) {
+ this.owner = employee;
+ }
+
+ public static class ID implements Serializable {
+ public long owner;
+ public String type;
+
+ public ID() {
+ }
+
+ public ID(int empId, String type) {
+ this.owner = empId;
+ this.type = type;
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof ID) {
+ final ID otherID = (ID) other;
+ return otherID.owner == this.owner && otherID.type.equals(type);
+ }
+ return false;
+ }
+
+ public int hashCode() {
+ return (int)this.owner + this.type.hashCode();
+ }
+ }
+}
diff --git a/batch-fetch/src/model/Project.java b/batch-fetch/src/model/Project.java
new file mode 100644
index 0000000..9144fdf
--- /dev/null
+++ b/batch-fetch/src/model/Project.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ * mbraeuer - annotated version
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+
+import javax.persistence.*;
+
+/**
+ * This class represent a project that a group of employees work on.
+ * This demonstrates JOINED inheritance.
+ */
+@Entity
+@Table(name="BF_PROJECT")
+@Inheritance(strategy = InheritanceType.JOINED)
+@DiscriminatorColumn(name = "PROJ_TYPE")
+public abstract class Project implements Serializable {
+ @Id
+ @Column(name = "PROJ_ID")
+ @GeneratedValue(strategy = GenerationType.SEQUENCE)
+ private int id;
+ @Basic
+ @Column(name = "PROJ_NAME")
+ private String name;
+ @Basic
+ @Column(name = "DESCRIP")
+ private String description;
+ @Version
+ private long version;
+ @ManyToOne(fetch = FetchType.LAZY)
+ @JoinColumn(name = "LEADER_ID")
+ private Employee teamLeader;
+
+ public Project() {
+ }
+
+ public String getDescription() {
+ return this.description;
+ }
+
+ public void setDescription(String descrip) {
+ this.description = descrip;
+ }
+
+ public int getId() {
+ return this.id;
+ }
+
+ public void setId(int projId) {
+ this.id = projId;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public void setName(String projName) {
+ this.name = projName;
+ }
+
+ public long getVersion() {
+ return version;
+ }
+
+ public void setVersion(long version) {
+ this.version = version;
+ }
+
+ public Employee getTeamLeader() {
+ return this.teamLeader;
+ }
+
+ public void setTeamLeader(Employee employee) {
+ this.teamLeader = employee;
+ }
+}
diff --git a/batch-fetch/src/model/SmallProject.java b/batch-fetch/src/model/SmallProject.java
new file mode 100644
index 0000000..41d0470
--- /dev/null
+++ b/batch-fetch/src/model/SmallProject.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * dclarke - initial JPA Employee example using XML (bug 217884)
+ * mbraeuer - annotated version
+ ******************************************************************************/
+package model;
+
+import javax.persistence.*;
+
+/**
+ * The SmallProject class demonstrates usage of a way to limit a subclass to its parent's table when JOINED
+ * inheritance is used. This avoids having to have an empty SMALLPROJECT table by setting the table to that
+ * of the superclass.
+ */
+@Entity
+@Table(name = "BF_PROJECT")
+@DiscriminatorValue("S")
+public class SmallProject extends Project {
+
+ private SmallProject() {
+ super();
+ }
+
+ public SmallProject(String name, String description) {
+ this();
+ setName(name);
+ setDescription(description);
+ }
+
+}
diff --git a/database-partitioning/.classpath b/database-partitioning/.classpath
new file mode 100644
index 0000000..4e2db7c
--- /dev/null
+++ b/database-partitioning/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/EclipseLink 1.2">
+ <attributes>
+ <attribute name="owner.project.facets" value="jpt.jpa;#system#"/>
+ </attributes>
+ </classpathentry>
+ <classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/Oracle JDBC"/>
+ <classpathentry kind="output" path="classes"/>
+</classpath>
diff --git a/database-partitioning/.project b/database-partitioning/.project
new file mode 100644
index 0000000..65bd5ef
--- /dev/null
+++ b/database-partitioning/.project
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>org.eclipse.persistence.example.jpa.partitioned</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.common.project.facet.core.builder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.wst.validation.validationbuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.wst.common.project.facet.core.nature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ <nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature>
+ <nature>org.eclipse.jem.workbench.JavaEMFNature</nature>
+ </natures>
+</projectDescription>
diff --git a/database-partitioning/build.xml b/database-partitioning/build.xml
new file mode 100644
index 0000000..fca54d2
--- /dev/null
+++ b/database-partitioning/build.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project basedir="." default="build" name="org.eclipse.persistence.example.jpa.partitioned">
+ <property environment="env"/>
+ <property name="JDBC_LIB" value="./mysql-connector-java-5.0.7-bin.jar"/>
+ <property name="JPA_LIB" value="./persistence.jar"/>
+ <property name="ECLIPSELINK_LIB" value="./eclipselink.jar"/>
+ <property name="AGENT" value="-javaagent:${ECLIPSELINK_LIB}"/>
+ <property name="debuglevel" value="source,lines,vars"/>
+ <path id="example.classpath">
+ <pathelement location="classes"/>
+ <pathelement location="${JDBC_LIB}"/>
+ <pathelement location="${JPA_LIB}"/>
+ <pathelement location="${ECLIPSELINK_LIB}"/>
+ </path>
+ <target name="init" depends="clean">
+ <mkdir dir="classes"/>
+ </target>
+ <target name="clean">
+ <delete dir="classes"/>
+ </target>
+
+ <target depends="init" name="build">
+ <echo message="${ant.project.name}: ${ant.file}"/>
+ <javac debug="true" debuglevel="${debuglevel}" destdir="classes">
+ <src path="src"/>
+ <exclude name="**/.svn/**"/>
+ <classpath refid="example.classpath"/>
+ </javac>
+ <copy file="src/META-INF/persistence.xml" todir="classes/META-INF"/>
+ </target>
+
+ <target name="test" depends="build">
+ <java classname="example.Test"
+ maxmemory="512m"
+ fork="true">
+ <jvmarg value="${AGENT}"/>
+ <classpath refid="example.classpath"/>
+ </java>
+ </target>
+</project>
diff --git a/database-partitioning/database-partitioning.zip b/database-partitioning/database-partitioning.zip
new file mode 100644
index 0000000..ac4a741
--- /dev/null
+++ b/database-partitioning/database-partitioning.zip
Binary files differ
diff --git a/database-partitioning/src/META-INF/persistence.xml b/database-partitioning/src/META-INF/persistence.xml
new file mode 100644
index 0000000..757f054
--- /dev/null
+++ b/database-partitioning/src/META-INF/persistence.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
+ version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
+ <persistence-unit name="order" transaction-type="RESOURCE_LOCAL">
+ <class>model.Order</class>
+ <class>model.OrderLine</class>
+ <class>model.Customer</class>
+ <properties>
+ <!-- Default database login using MySQL for EclipseLink's internal connection pool,
+ change this to access your own database. -->
+ <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
+ <property name="javax.persistence.jdbc.url" value="jdbc:mysql://node1:3306/mysql" />
+ <property name="javax.persistence.jdbc.user" value="root" />
+ <property name="javax.persistence.jdbc.password" value="password" />
+
+ <!-- The database platform is auto-detected by default,
+ if you want to set a specific platform this can be set. -->
+ <!-- property name=""eclipselink.target-database" value="Oracle" / -->
+
+ <!-- Configure connection pool. -->
+ <property name="eclipselink.connection-pool.default.initial" value="1" />
+ <property name="eclipselink.connection-pool.default.min" value="64" />
+ <property name="eclipselink.connection-pool.default.max" value="64" />
+
+ <!-- Configure 2nd database connection pool. -->
+ <property name="eclipselink.connection-pool.node2.url" value="jdbc:mysql://node2:3306/mysql" />
+ <property name="eclipselink.connection-pool.node2.user" value="root" />
+ <property name="eclipselink.connection-pool.node2.password" value="password" />
+ <property name="eclipselink.connection-pool.node2.initial" value="1" />
+ <property name="eclipselink.connection-pool.node2.min" value="64" />
+ <property name="eclipselink.connection-pool.node2.max" value="64" />
+
+ <!-- Default partioning to replication to allow DDL to be sent to all nodes -->
+ <property name="eclipselink.partitioning" value="Replicate" />
+
+ <!-- Enabled statement caching, this is only required when using internal connection pooling,
+ when using a DataSource, statement caching must be configured in the DataSource. -->
+ <property name="eclipselink.jdbc.cache-statements" value="true" />
+
+ <!-- In JSE no server platform is used, if you wish to use this example is a JEE server with JTA,
+ then you need to set this. -->
+ <!-- property name="eclipselink.target-server" value="WebLogic" / -->
+
+ <!-- Caching is disabled for this example to stress the database more. -->
+ <property name="eclipselink.cache.shared.default" value="false" />
+
+ <!-- If desired, this option would force a JDBC connection to be held for the duration of an EntityManager,
+ instead of returned to the pool in between queries/transactions. -->
+ <!-- property name="eclipselink.jdbc.exclusive-connection.mode" value="Always" / -->
+
+ <!-- Configure database to be created on startup if not already existing. -->
+ <!-- property name="eclipselink.ddl-generation" value="create-tables" / -->
+ <!-- To drop and replace existing schema this can be used. -->
+ <!-- property name="eclipselink.ddl-generation" value="drop-and-create-tables" / -->
+
+ <!-- Configure logging for demonstration. -->
+ <!-- property name="eclipselink.logging.level" value="FINE" / -->
+ </properties>
+ </persistence-unit>
+</persistence>
diff --git a/database-partitioning/src/example/Test.java b/database-partitioning/src/example/Test.java
new file mode 100644
index 0000000..d5a3438
--- /dev/null
+++ b/database-partitioning/src/example/Test.java
@@ -0,0 +1,222 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * Oracle - initial impl
+ ******************************************************************************/
+package example;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+
+import model.*;
+
+/**
+ * Simulates a large load of order processing.
+ * @author James Sutherland
+ */
+public class Test {
+
+ public static int REPEATS = 5;
+ public static int THREADS = 16;
+ public static int RUN_TIME = 600;//60000; //1 minute.
+
+ protected static volatile int executions;
+
+ /**
+ * Measure the performance of the run.
+ * Repeat the run REPEATS (5) times,
+ * and measure the number of execution in RUN_TIME (60s).
+ */
+ public static void executeRun(String name, final Runnable runnable) {
+ System.out.println("Starting run: " + name);
+
+ List<Integer> results = new ArrayList<Integer>();
+ // Repeat the test and baseline for the number of repeats.
+ for (int repeat = 0; repeat < REPEATS; repeat++) {
+ System.gc();
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException ignore) {}
+ executions = 0;
+ Thread[] threads = new Thread[THREADS];
+ for (int thread = 0; thread < THREADS; thread++) {
+ Runnable worker = new Runnable() {
+ public void run() {
+ long startTime, endTime;
+ startTime = System.currentTimeMillis();
+ endTime = startTime;
+ // Count how many times the test can be invoked in the run time.
+ // This allows for the test run time to be easily changed.
+ while ((startTime + RUN_TIME) >= endTime) {
+ runnable.run();
+ executions++;
+ endTime = System.currentTimeMillis();
+ }
+ }
+ };
+ threads[thread] = new Thread(worker);
+ }
+ for (Thread thread : threads) {
+ thread.start();
+ }
+ for (Thread thread : threads) {
+ try {
+ thread.join();
+ } catch (InterruptedException ignore) {}
+ }
+ results.add(executions);
+ System.out.println("Done run: " + repeat + " for: " + name);
+ }
+
+ System.out.println("Completed run: " + name);
+
+ System.out.println("");
+ System.out.println(name + " Results");
+ System.out.println("Run repeats:" + REPEATS);
+ System.out.println("Run threads:" + THREADS);
+ System.out.println("Run time:" + RUN_TIME + "ms");
+ System.out.println("Average result:" + averageResults(results));
+ System.out.println("Max result:" + maxResults(results));
+ System.out.println("Min result:" + minResults(results));
+ System.out.println("% standard deviation:" + standardDeviationResults(results));
+ System.out.println("");
+ System.out.println("");
+ }
+
+ /**
+ * Compute the max of the results.
+ */
+ public static int maxResults(List<Integer> times) {
+ int testMax = 0;
+ for (int index = 0; index < times.size(); index++) {
+ int time = times.get(index);
+ if (time > testMax) {
+ testMax = time;
+ }
+ }
+ return testMax;
+ }
+
+ /**
+ * Compute the min of the results.
+ */
+ public static int minResults(List<Integer> times) {
+ int testMin = 0;
+ for (int index = 0; index < times.size(); index++) {
+ int time = times.get(index);
+ if ((testMin == 0) || (time < testMin)) {
+ testMin = time;
+ }
+ }
+ return testMin;
+ }
+
+ /**
+ * Filter max and min from results.
+ */
+ public static List<Integer> filterMaxMinResults(List<Integer> times) {
+ List filteredTimes = new ArrayList(times);
+ if (filteredTimes.size() > 3) {
+ filteredTimes.remove((Integer)maxResults(times));
+ filteredTimes.remove((Integer)minResults(times));
+ }
+ return filteredTimes;
+ }
+
+ /**
+ * Compute the average of the results rejecting the min and max.
+ */
+ public static double averageResults(List<Integer> allTimes) {
+ // Compute the average reject the min and max to improve consistency.
+ List<Integer> times = filterMaxMinResults(allTimes);
+ double testAverage = 0;
+ for (int index = 0; index < times.size(); index++) {
+ int time = times.get(index);
+ testAverage = testAverage + time;
+ }
+ testAverage = testAverage / times.size();
+ return testAverage;
+ }
+
+ /**
+ * Compute the standard deviation of the results rejecting the min and max.
+ */
+ public static double standardDeviationResults(List<Integer> allTimes) {
+ // Compute the average reject the min and max to improve consistency.
+ double testAverage = averageResults(allTimes);
+
+ // Compute the standard deviation reject the min and max to improve consistency.
+ List<Integer> times = filterMaxMinResults(allTimes);
+ double testStandardDeviation = 0;
+ for (int index = 0; index < times.size(); index++) {
+ int time = times.get(index);
+ testStandardDeviation = testStandardDeviation + Math.pow(time - testAverage, 2);
+ }
+ testStandardDeviation = testStandardDeviation / times.size();
+ testStandardDeviation = Math.sqrt(testStandardDeviation);
+ // As percent of average
+ testStandardDeviation = (testStandardDeviation / testAverage) * 100;
+ return testStandardDeviation;
+ }
+
+
+ public static void main(String[] args) throws Exception {
+ final EntityManagerFactory emf = Persistence.createEntityManagerFactory("order");
+ EntityManager em = emf.createEntityManager();
+ // Drop constraint to allow cross partition relationship.
+ em.getTransaction().begin();
+ em.createNativeQuery("ALTER TABLE PART_ORDER DROP FOREIGN KEY FK_PART_ORDER_CUSTOMER_ID").executeUpdate();
+ em.getTransaction().commit();
+ em.close();
+ executeRun("place-orders", new Runnable() {
+ ThreadLocal<Customer> customer = new ThreadLocal<Customer>();
+ public void run() {
+ Test test = new Test();
+ if (customer.get() == null) {
+ customer.set(test.createCustomer(emf));
+ }
+ test.placeOrder(customer.get(), emf);
+ }
+ });
+ emf.close();
+ }
+
+ public Customer createCustomer(EntityManagerFactory emf) {
+ EntityManager em = emf.createEntityManager();
+ Customer customer = new Customer();
+ customer.setName("AMCE-" + System.currentTimeMillis());
+ em.getTransaction().begin();
+ em.persist(customer);
+ em.getTransaction().commit();
+ em.close();
+ return customer;
+ }
+
+ public Order placeOrder(Customer customer, EntityManagerFactory emf) {
+ EntityManager em = emf.createEntityManager();
+ customer = em.find(customer.getClass(), customer.getId());
+ Order order = new Order();
+ order.setDescription("Order-" + System.currentTimeMillis());
+ for (int index = 0; index<10; index++) {
+ order.addOrderLine(new OrderLine("item-" + index, new BigDecimal(index * 100)));
+ }
+ customer.addOrder(order);
+ em.getTransaction().begin();
+ em.persist(order);
+ em.getTransaction().commit();
+ em.close();
+ return order;
+ }
+}
diff --git a/database-partitioning/src/model/Customer.java b/database-partitioning/src/model/Customer.java
new file mode 100644
index 0000000..ce46b37
--- /dev/null
+++ b/database-partitioning/src/model/Customer.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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:
+ * Oracle - initial impl
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.*;
+
+import org.eclipse.persistence.annotations.HashPartitioning;
+import org.eclipse.persistence.annotations.Partitioned;
+import org.eclipse.persistence.annotations.ReplicationPartitioning;
+
+/**
+ * Customer, hash partitioned by Id.
+ * @author James Sutherland
+ */
+@Entity
+@Table(name="PART_CUSTOMER")
+@ReplicationPartitioning(name="Replicate", connectionPools={"default","node2"})
+@HashPartitioning(name="HashPartitionById", partitionColumn=@Column(name="ID"), connectionPools={"default","node2"})
+@Partitioned("HashPartitionById")
+public class Customer implements Serializable {
+ @Id
+ @GeneratedValue(strategy=GenerationType.TABLE)
+ private long id;
+ @Basic
+ private String name;
+ @OneToMany(mappedBy="customer")
+ private List<Order> orders = new ArrayList<Order>();
+
+ public Customer() {
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public List<Order> getOrders() {
+ return orders;
+ }
+
+ public void setOrders(List<Order> orders) {
+ this.orders = orders;
+ }
+
+ public void addOrder(Order order) {
+ order.setCustomer(this);
+ getOrders().add(order);
+ }
+}
diff --git a/database-partitioning/src/model/Order.java b/database-partitioning/src/model/Order.java
new file mode 100644
index 0000000..12d36d0
--- /dev/null
+++ b/database-partitioning/src/model/Order.java
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 1998, 2012 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:
+ * Oracle - initial impl
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.persistence.*;
+
+import org.eclipse.persistence.annotations.HashPartitioning;
+import org.eclipse.persistence.annotations.Partitioned;
+
+/**
+ * Order, hash partitioned by the Order's Id.
+ * @author James Sutherland
+ */
+@Entity
+@Table(name="PART_ORDER")
+@HashPartitioning(name="HashPartitionByOrderId", partitionColumn=@Column(name="ORDER_ID"), connectionPools={"default","node2"})
+@Partitioned("HashPartitionByOrderId")
+public class Order implements Serializable {
+ @Id
+ @GeneratedValue(strategy=GenerationType.TABLE)
+ @Column(name="ORDER_ID")
+ private long id;
+ @Basic
+ private String description;
+ @Basic
+ private BigDecimal totalCost = BigDecimal.valueOf(0);
+ @OneToMany(mappedBy="order", cascade=CascadeType.ALL, orphanRemoval=true)
+ @OrderBy("lineNumber")
+ private List<OrderLine> orderLines = new ArrayList<OrderLine>();
+ @ManyToOne(fetch=FetchType.LAZY)
+ private Customer customer;
+
+ public Order() {
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public BigDecimal getTotalCost() {
+ return totalCost;
+ }
+
+ public void setTotalCost(BigDecimal totalCost) {
+ this.totalCost = totalCost;
+ }
+
+ public List<OrderLine> getOrderLines() {
+ return orderLines;
+ }
+
+ public void setOrderLines(List<OrderLine> orderLines) {
+ this.orderLines = orderLines;
+ }
+
+ public Customer getCustomer() {
+ return customer;
+ }
+
+ public void setCustomer(Customer customer) {
+ this.customer = customer;
+ }
+
+ /**
+ * Add the order line to the order, and set the back reference and update the order cost.
+ */
+ public void addOrderLine(OrderLine orderLine) {
+ orderLine.setOrder(this);
+ getOrderLines().add(orderLine);
+ orderLine.setLineNumber(getOrderLines().size());
+ setTotalCost(getTotalCost().add(orderLine.getCost()));
+ }
+}
diff --git a/database-partitioning/src/model/OrderLine.java b/database-partitioning/src/model/OrderLine.java
new file mode 100644
index 0000000..0ef8ce2
--- /dev/null
+++ b/database-partitioning/src/model/OrderLine.java
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2011, 2012 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:
+ * Oracle - initial impl
+ ******************************************************************************/
+package model;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+import javax.persistence.*;
+
+import org.eclipse.persistence.annotations.Partitioned;
+
+/**
+ * OrderLine, help by Order, hash partitioned by the Order's Id.
+ * @author James Sutherland
+ */
+@Entity
+@Table(name="PART_ORDERLINE")
+@Partitioned("HashPartitionByOrderId")
+public class OrderLine implements Serializable {
+ @Id
+ @ManyToOne(fetch=FetchType.LAZY)
+ @JoinColumn(name="ORDER_ID")
+ private Order order;
+ @Id
+ private int lineNumber;
+ @Basic
+ private String description;
+ @Basic
+ private BigDecimal cost = BigDecimal.valueOf(0);
+
+ public OrderLine() {
+ }
+
+ public OrderLine(String description, BigDecimal cost) {
+ this.description = description;
+ this.cost = cost;
+ }
+
+ public Order getOrder() {
+ return order;
+ }
+
+ public void setOrder(Order order) {
+ this.order = order;
+ }
+
+ public int getLineNumber() {
+ return lineNumber;
+ }
+
+ public void setLineNumber(int lineNumber) {
+ this.lineNumber = lineNumber;
+ }
+
+ public String getDescription() {
+ return description;
+ }
+
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ public BigDecimal getCost() {
+ return cost;
+ }
+
+ public void setCost(BigDecimal cost) {
+ this.cost = cost;
+ }
+
+}