From 819514f157d0c7c4a5cf9393525ddeead1b22be1 Mon Sep 17 00:00:00 2001 From: Pinaki Poddar Date: Fri, 30 Jan 2009 03:51:10 +0000 Subject: [PATCH] Cache EntityManagerFactory for better performance git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@739158 13f79535-47bb-0310-9956-ffa450edef68 --- .../persistence/test/PersistenceTestCase.java | 68 ++++++++++++++++--- 1 file changed, 58 insertions(+), 10 deletions(-) diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java index f969655fe..254eec714 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/test/PersistenceTestCase.java @@ -27,29 +27,40 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.sql.SQLException; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.HashMap; + import javax.persistence.EntityManager; import javax.persistence.EntityManagerFactory; import javax.persistence.Persistence; -import junit.framework.AssertionFailedError; import junit.framework.TestCase; import junit.framework.TestResult; + import org.apache.openjpa.kernel.AbstractBrokerFactory; import org.apache.openjpa.kernel.Broker; import org.apache.openjpa.meta.ClassMetaData; -import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; import org.apache.openjpa.persistence.JPAFacadeHelper; +import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI; /** * Base test class providing persistence utilities. + * + * EntityManagerFactory created by this receiver is statically cached indexed + * by a key which is a combination of the persistence unit name and the user + * configuration. + * If a extended test does not want cached EntityManagerFactory + * then it must specify FRESH_EMF as one of the arguments of #setUp(Object[]). + * + * */ public abstract class PersistenceTestCase extends TestCase { - + private static FixedMap _emfs = new FixedMap(); + public static final String FRESH_EMF = "Creates new EntityManagerFactory"; /** * Marker object you pass to {@link #setUp} to indicate that the * database table rows should be cleared. @@ -98,10 +109,15 @@ public abstract class PersistenceTestCase */ protected OpenJPAEntityManagerFactorySPI createNamedEMF(String pu, Object... props) { - Map map = new HashMap(System.getProperties()); + Map map = new HashMap();//System.getProperties()); List types = new ArrayList(); boolean prop = false; + boolean fresh = false; for (int i = 0; i < props.length; i++) { + if (props[i] == FRESH_EMF) { + fresh = true; + continue; + } if (prop) { map.put(props[i - 1], props[i]); prop = false; @@ -131,13 +147,21 @@ public abstract class PersistenceTestCase map.put("openjpa.MetaDataFactory", "jpa(Types=" + buf.toString() + oldValue + ")"); } - - OpenJPAEntityManagerFactorySPI oemf = (OpenJPAEntityManagerFactorySPI) - Persistence.createEntityManagerFactory(pu, map); - if (oemf == null) - throw new NullPointerException( + EMFKey key = new EMFKey(pu, map); + OpenJPAEntityManagerFactorySPI oemf = _emfs.get(key); + if (fresh || oemf == null) { + Map config = new HashMap(System.getProperties()); + config.putAll(map); + oemf = (OpenJPAEntityManagerFactorySPI) + Persistence.createEntityManagerFactory(pu, config); + if (oemf == null) { + throw new NullPointerException( "Expected an entity manager factory " + "for the persistence unit named: \"" + pu + "\""); + } else if (!fresh) { + _emfs.put(key, oemf); + } + } return oemf; } @@ -447,4 +471,28 @@ public abstract class PersistenceTestCase return anno.value(); return false; } + + private static class FixedMap extends LinkedHashMap { + public boolean removeEldestEntry(Map.Entry entry) { + return this.size() > 2; + } + } + + private static class EMFKey { + final String unit; + final Map config; + EMFKey(String unit, Map config) { + this.unit = unit; + this.config = config; + } + + public int hashCode() { + return unit.hashCode() + config.hashCode(); + } + + public boolean equals(Object other) { + EMFKey that = (EMFKey)other; + return unit.equals(that.unit) && config.equals(that.config); + } + } }