Cache EntityManagerFactory for better performance

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@739158 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Pinaki Poddar 2009-01-30 03:51:10 +00:00
parent 6453c64343
commit 819514f157
1 changed files with 58 additions and 10 deletions

View File

@ -27,29 +27,40 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.HashMap;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence; import javax.persistence.Persistence;
import junit.framework.AssertionFailedError;
import junit.framework.TestCase; import junit.framework.TestCase;
import junit.framework.TestResult; import junit.framework.TestResult;
import org.apache.openjpa.kernel.AbstractBrokerFactory; import org.apache.openjpa.kernel.AbstractBrokerFactory;
import org.apache.openjpa.kernel.Broker; import org.apache.openjpa.kernel.Broker;
import org.apache.openjpa.meta.ClassMetaData; import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
import org.apache.openjpa.persistence.JPAFacadeHelper; import org.apache.openjpa.persistence.JPAFacadeHelper;
import org.apache.openjpa.persistence.OpenJPAEntityManagerFactorySPI;
/** /**
* Base test class providing persistence utilities. * 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 public abstract class PersistenceTestCase
extends TestCase { 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 * Marker object you pass to {@link #setUp} to indicate that the
* database table rows should be cleared. * database table rows should be cleared.
@ -98,10 +109,15 @@ public abstract class PersistenceTestCase
*/ */
protected OpenJPAEntityManagerFactorySPI createNamedEMF(String pu, protected OpenJPAEntityManagerFactorySPI createNamedEMF(String pu,
Object... props) { Object... props) {
Map map = new HashMap(System.getProperties()); Map map = new HashMap();//System.getProperties());
List<Class> types = new ArrayList<Class>(); List<Class> types = new ArrayList<Class>();
boolean prop = false; boolean prop = false;
boolean fresh = false;
for (int i = 0; i < props.length; i++) { for (int i = 0; i < props.length; i++) {
if (props[i] == FRESH_EMF) {
fresh = true;
continue;
}
if (prop) { if (prop) {
map.put(props[i - 1], props[i]); map.put(props[i - 1], props[i]);
prop = false; prop = false;
@ -131,13 +147,21 @@ public abstract class PersistenceTestCase
map.put("openjpa.MetaDataFactory", map.put("openjpa.MetaDataFactory",
"jpa(Types=" + buf.toString() + oldValue + ")"); "jpa(Types=" + buf.toString() + oldValue + ")");
} }
EMFKey key = new EMFKey(pu, map);
OpenJPAEntityManagerFactorySPI oemf = (OpenJPAEntityManagerFactorySPI) OpenJPAEntityManagerFactorySPI oemf = _emfs.get(key);
Persistence.createEntityManagerFactory(pu, map); if (fresh || oemf == null) {
if (oemf == null) Map config = new HashMap(System.getProperties());
throw new NullPointerException( config.putAll(map);
oemf = (OpenJPAEntityManagerFactorySPI)
Persistence.createEntityManagerFactory(pu, config);
if (oemf == null) {
throw new NullPointerException(
"Expected an entity manager factory " + "Expected an entity manager factory " +
"for the persistence unit named: \"" + pu + "\""); "for the persistence unit named: \"" + pu + "\"");
} else if (!fresh) {
_emfs.put(key, oemf);
}
}
return oemf; return oemf;
} }
@ -447,4 +471,28 @@ public abstract class PersistenceTestCase
return anno.value(); return anno.value();
return false; return false;
} }
private static class FixedMap extends LinkedHashMap<EMFKey, OpenJPAEntityManagerFactorySPI> {
public boolean removeEldestEntry(Map.Entry<EMFKey, OpenJPAEntityManagerFactorySPI> 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);
}
}
} }