From ca57f3e4753e17bba76035f409c34f579bfd71c0 Mon Sep 17 00:00:00 2001 From: Dancovich Date: Tue, 14 Aug 2012 17:56:43 -0300 Subject: [PATCH] Alterada forma como cache de entity manager factory é gerada, evitando recarregar o cache a cada chamada do producer. --- impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducer.java | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------- impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties | 1 + impl/extension/jpa/src/test/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducerTest.java | 4 ++-- impl/extension/jpa/src/test/resources/demoiselle-jpa-bundle.properties | 1 + 4 files changed, 58 insertions(+), 75 deletions(-) diff --git a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducer.java b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducer.java index 71eaf75..14937b5 100644 --- a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducer.java +++ b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducer.java @@ -1,10 +1,12 @@ package br.gov.frameworkdemoiselle.internal.producer; import java.io.Serializable; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.enterprise.context.ApplicationScoped; import javax.inject.Inject; @@ -40,32 +42,42 @@ public class EntityManagerFactoryProducer implements Serializable { // private final Map cache = Collections // .synchronizedMap(new HashMap()); - private final Map cache = Collections - .synchronizedMap(new HashMap()); + /* + * private final Map cache = Collections .synchronizedMap(new HashMap()); + */ + + private final Map> factoryCache = Collections + .synchronizedMap(new HashMap>()); public EntityManagerFactory create(String persistenceUnit) { EntityManagerFactory factory; - //String[] key = new String [] { persistenceUnit, Thread.currentThread().getContextClassLoader().toString()}; - Key key = new Key(persistenceUnit, Thread.currentThread().getContextClassLoader()); - - if (cache.containsKey(key)) { - factory = cache.get(key); + ClassLoader c = Thread.currentThread().getContextClassLoader(); + + if (factoryCache.containsKey(c)) { + Map localCache = factoryCache.get(c); + if (localCache.containsKey(persistenceUnit)) { + factory = localCache.get(persistenceUnit); + } else { + factory = Persistence.createEntityManagerFactory(persistenceUnit); + localCache.put(persistenceUnit, factory); + } } else { + Map localCache = new HashMap(); factory = Persistence.createEntityManagerFactory(persistenceUnit); - cache.put(key, factory); + localCache.put(persistenceUnit, factory); + factoryCache.put(c, localCache); } return factory; } - // @PostConstruct - public void init() { - ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); - + private String[] loadPersistenceUnitFromClassloader(ClassLoader classLoader) { try { + ArrayList persistenceUnits = new ArrayList(); DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); - Document document = documentBuilder.parse(contextClassLoader.getResourceAsStream(ENTITY_MANAGER_RESOURCE)); + Document document = documentBuilder.parse(classLoader.getResourceAsStream(ENTITY_MANAGER_RESOURCE)); NodeList nodes = document.getElementsByTagName("persistence-unit"); String persistenceUnit = ""; @@ -75,88 +87,57 @@ public class EntityManagerFactoryProducer implements Serializable { if ("".equals(persistenceUnit)) { throw new DemoiselleException(bundle.getString("can-not-get-persistence-unit-from-persistence")); + } else { + persistenceUnits.add(persistenceUnit); } + // logger.debug(bundle.getString("persistence-unit-name-found", + // persistenceUnit)); - create(persistenceUnit); - logger.debug(bundle.getString("persistence-unit-name-found", persistenceUnit)); } + return persistenceUnits.toArray(new String[0]); + } catch (Exception cause) { String message = bundle.getString("can-not-get-persistence-unit-from-persistence"); logger.error(message, cause); throw new DemoiselleException(message, cause); } + + } + + @PostConstruct + public void loadPersistenceUnits() { + ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); + for (String persistenceUnit : loadPersistenceUnitFromClassloader(contextClassLoader)) { + create(persistenceUnit); + logger.debug(bundle.getString("persistence-unit-name-found", persistenceUnit)); + } } @PreDestroy public void close() { - for (EntityManagerFactory factory : cache.values()) { - factory.close(); + for (Map factories : factoryCache.values()) { + for (EntityManagerFactory factory : factories.values()) { + factory.close(); + } } - - cache.clear(); + factoryCache.clear(); } public Map getCache() { - init(); - Map result = new HashMap(); ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); - - for (Key key : cache.keySet()) { - if(key.classLoader.equals(classLoader)) { - result.put(key.persistenceUnit, cache.get(key)); - } - } - - return result; - } - - - class Key{ - - private String persistenceUnit; - private ClassLoader classLoader; - - - public Key(String persistenceUnit, ClassLoader classLoader) { - this.persistenceUnit = persistenceUnit; - this.classLoader = classLoader; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((classLoader == null) ? 0 : classLoader.hashCode()); - result = prime * result + ((persistenceUnit == null) ? 0 : persistenceUnit.hashCode()); - return result; - } + Map result = factoryCache.get(classLoader); - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - Key other = (Key) obj; - if (classLoader == null) { - if (other.classLoader != null) - return false; - } else if (!classLoader.equals(other.classLoader)) - return false; - if (persistenceUnit == null) { - if (other.persistenceUnit != null) - return false; - } else if (!persistenceUnit.equals(other.persistenceUnit)) - return false; - return true; + if (result == null || result.isEmpty()) { + logger.debug(bundle.getString("entity-manager-factory-not-found-in-cache")); + for (String persistenceUnit : loadPersistenceUnitFromClassloader(classLoader)) { + create(persistenceUnit); + result = factoryCache.get(classLoader); + } } + return result; } } - - diff --git a/impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties b/impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties index 9dde8ee..40621da 100644 --- a/impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties +++ b/impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties @@ -34,6 +34,7 @@ # 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. entity-manager-was-created=Gerenciador de entidades criado a partir da unidade de persist\u00EAncia "{0}". +entity-manager-factory-not-found-in-cache=Entity Manager Factory n\u00E3o encontrado para contexto atual, criando um agora. operation-not-supported=Esta operação não é suportada. getting-persistence-unit-from-properties=Obtendo a unidade de persist\u00EAncia a partir do arquivo de configura\u00E7\u00E3o "{0}". getting-persistence-unit-from-persistence=Obtendo a unidade de persist\u00EAncia a partir do arquivo "persistence.xml". diff --git a/impl/extension/jpa/src/test/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducerTest.java b/impl/extension/jpa/src/test/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducerTest.java index 41814bc..66f7295 100644 --- a/impl/extension/jpa/src/test/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducerTest.java +++ b/impl/extension/jpa/src/test/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerFactoryProducerTest.java @@ -72,14 +72,14 @@ public class EntityManagerFactoryProducerTest { expect(Persistence.createEntityManagerFactory("pu1")).andReturn(emFactory); replay(Persistence.class); - producer.init(); + producer.loadPersistenceUnits(); Assert.assertEquals(emFactory, cache.get("pu1")); } @Test public void testInitWithError() { try { - producer.init(); + producer.loadPersistenceUnits(); Assert.fail(); }catch(DemoiselleException cause) { Assert.assertTrue(true); diff --git a/impl/extension/jpa/src/test/resources/demoiselle-jpa-bundle.properties b/impl/extension/jpa/src/test/resources/demoiselle-jpa-bundle.properties index 9dde8ee..40621da 100644 --- a/impl/extension/jpa/src/test/resources/demoiselle-jpa-bundle.properties +++ b/impl/extension/jpa/src/test/resources/demoiselle-jpa-bundle.properties @@ -34,6 +34,7 @@ # 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. entity-manager-was-created=Gerenciador de entidades criado a partir da unidade de persist\u00EAncia "{0}". +entity-manager-factory-not-found-in-cache=Entity Manager Factory n\u00E3o encontrado para contexto atual, criando um agora. operation-not-supported=Esta operação não é suportada. getting-persistence-unit-from-properties=Obtendo a unidade de persist\u00EAncia a partir do arquivo de configura\u00E7\u00E3o "{0}". getting-persistence-unit-from-persistence=Obtendo a unidade de persist\u00EAncia a partir do arquivo "persistence.xml". -- libgit2 0.21.2