blob: 5539adc806100643034c97f886a88790ab895fbb [file] [log] [blame]
/*******************************************************************************
* 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();
}
}