diff --git a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/ConfigurationEnumValueExtractor.java b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/ConfigurationEnumValueExtractor.java index 8560294..81a5c7c 100644 --- a/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/ConfigurationEnumValueExtractor.java +++ b/impl/core/src/main/java/br/gov/frameworkdemoiselle/internal/implementation/ConfigurationEnumValueExtractor.java @@ -56,10 +56,10 @@ public class ConfigurationEnumValueExtractor implements ConfigurationValueExtrac String value = configuration.getString(prefix + key); if (value!=null){ - Object enums[] = field.getDeclaringClass().getEnumConstants(); + Object enums[] = field.getType().getEnumConstants(); for (int i=0; i)enums[i]).toString().equalsIgnoreCase(value) ){ return enums[i]; } } diff --git a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/EntityManagerBootstrap.java b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/EntityManagerBootstrap.java index 3cb2204..5de7213 100644 --- a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/EntityManagerBootstrap.java +++ b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/EntityManagerBootstrap.java @@ -1,8 +1,45 @@ +/* + * Demoiselle Framework + * Copyright (C) 2010 SERPRO + * ---------------------------------------------------------------------------- + * This file is part of Demoiselle Framework. + * + * Demoiselle Framework is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License version 3 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License version 3 + * along with this program; if not, see + * or write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + * ---------------------------------------------------------------------------- + * Este arquivo é parte do Framework Demoiselle. + * + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação + * do Software Livre (FSF). + * + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português + * para maiores detalhes. + * + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título + * "LICENCA.txt", junto com esse programa. Se não, acesse + * ou escreva para a Fundação do Software Livre (FSF) Inc., + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. + */ package br.gov.frameworkdemoiselle.internal.bootstrap; import java.lang.annotation.Annotation; import java.lang.reflect.Type; -import java.net.URL; +import java.util.Collections; +import java.util.HashSet; import java.util.Locale; import java.util.Set; @@ -10,18 +47,20 @@ import javax.enterprise.context.ApplicationScoped; import javax.enterprise.context.ConversationScoped; import javax.enterprise.context.RequestScoped; import javax.enterprise.context.SessionScoped; +import javax.enterprise.event.Observes; import javax.enterprise.inject.spi.AnnotatedConstructor; import javax.enterprise.inject.spi.AnnotatedField; import javax.enterprise.inject.spi.AnnotatedMethod; import javax.enterprise.inject.spi.AnnotatedType; -import javax.enterprise.inject.spi.BeanManager; import javax.enterprise.inject.spi.Extension; import javax.enterprise.inject.spi.ProcessAnnotatedType; -import javax.enterprise.inject.spi.ProcessBean; +import javax.enterprise.util.AnnotationLiteral; +import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.slf4j.Logger; +import br.gov.frameworkdemoiselle.DemoiselleException; import br.gov.frameworkdemoiselle.annotation.Name; import br.gov.frameworkdemoiselle.annotation.ViewScoped; import br.gov.frameworkdemoiselle.configuration.Configuration; @@ -37,151 +76,158 @@ public class EntityManagerBootstrap implements Extension { private transient ResourceBundle bundle; - private EntityManagerScope selectedScope; + private static final String DEMOISELLE_PROPERTIES_FILE_NAME = "demoiselle.properties"; - public void replaceAnnotatedType(final ProcessAnnotatedType event , BeanManager manager){ + public void makeScoped(@Observes ProcessAnnotatedType event){ + final AnnotatedType type = event.getAnnotatedType(); + final EntityManagerScope scope = getConfiguredEntityManagerScope(); - if (event.getAnnotatedType().getJavaClass().equals(EntityManagerProducer.class)){ - AnnotatedType wrapper = new AnnotatedType() { - - private final AnnotatedType delegate = event.getAnnotatedType(); - - public Class getJavaClass() { - return delegate.getJavaClass(); - } - - public Type getBaseType() { - return delegate.getBaseType(); - } - - public Set> getConstructors() { - return delegate.getConstructors(); - } - - public Set getTypeClosure() { - return delegate.getTypeClosure(); - } - - public Set> getMethods() { - return delegate.getMethods(); - } - - public T getAnnotation(Class annotationType) { - return delegate.getAnnotation(annotationType); - - /*T returnedAnnotation; - switch(getConfiguredEntityManagerScope()){ + AnnotatedType newType = new AnnotatedType() { + + private AnnotatedType delegate = type; + private AnnotationLiteral scopedLiteral; + private Class expectedScopedAnnotationType; + private boolean initialized = false; + private Set annotations; + + private void initialize(){ + if (!initialized){ + switch (scope) { case APPLICATION: - returnedAnnotation = (T) (annotationType.equals(ApplicationScoped.class) ? new AnnotationLiteral() { - private static final long serialVersionUID = 1L; - } : delegate.getAnnotation(annotationType)); + expectedScopedAnnotationType = ApplicationScoped.class; + scopedLiteral = new ApplicationLiteral(); + break; case CONVERSATION: - returnedAnnotation = (T) (annotationType.equals(ConversationScoped.class) ? new AnnotationLiteral() { - private static final long serialVersionUID = 1L; - } : delegate.getAnnotation(annotationType)); + expectedScopedAnnotationType = ConversationScoped.class; + scopedLiteral = new ConversationLiteral(); + break; case NOSCOPE: - returnedAnnotation = delegate.getAnnotation(annotationType); + expectedScopedAnnotationType = null; + scopedLiteral = null; + break; case REQUEST: - returnedAnnotation = (T) (annotationType.equals(RequestScoped.class) ? new AnnotationLiteral() { - private static final long serialVersionUID = 1L; - } : delegate.getAnnotation(annotationType)); + expectedScopedAnnotationType = RequestScoped.class; + scopedLiteral = new RequestLiteral(); + break; case SESSION: - returnedAnnotation = (T) (annotationType.equals(SessionScoped.class) ? new AnnotationLiteral() { - private static final long serialVersionUID = 1L; - } : delegate.getAnnotation(annotationType)); + expectedScopedAnnotationType = SessionScoped.class; + scopedLiteral = new SessionLiteral(); + break; case VIEW: - returnedAnnotation = (T) (annotationType.equals(ViewScoped.class) ? new AnnotationLiteral() { - private static final long serialVersionUID = 1L; - } : delegate.getAnnotation(annotationType)); + expectedScopedAnnotationType = ViewScoped.class; + scopedLiteral = new ViewLiteral(); + break; default: - returnedAnnotation = delegate.getAnnotation(annotationType); + expectedScopedAnnotationType = null; + scopedLiteral = null; + break; } - return returnedAnnotation;*/ + initialized = true; } + } - public Set> getFields() { - return delegate.getFields(); - } + public Class getJavaClass() { + return delegate.getJavaClass(); + } + + public Type getBaseType() { + return delegate.getBaseType(); + } + + public Set> getConstructors() { + return delegate.getConstructors(); + } - public Set getAnnotations() { - return delegate.getAnnotations(); + public Set getTypeClosure() { + return delegate.getTypeClosure(); + } + + public Set> getMethods() { + return delegate.getMethods(); + } + + @SuppressWarnings("unchecked") + public T getAnnotation(Class annotationType) { + initialize(); + + if (expectedScopedAnnotationType!=null && expectedScopedAnnotationType.isAssignableFrom(annotationType)){ + return (T) scopedLiteral; } + else{ + return delegate.getAnnotation(annotationType); + } + } - public boolean isAnnotationPresent(Class annotationType) { - switch(getConfiguredEntityManagerScope()){ - case APPLICATION: - return annotationType.equals(ApplicationScoped.class) ? true : delegate.isAnnotationPresent(annotationType); - case CONVERSATION: - return annotationType.equals(ConversationScoped.class) ? true : delegate.isAnnotationPresent(annotationType); - case NOSCOPE: - return delegate.isAnnotationPresent(annotationType); - case REQUEST: - return annotationType.equals(RequestScoped.class) ? true : delegate.isAnnotationPresent(annotationType); - case SESSION: - return annotationType.equals(SessionScoped.class) ? true : delegate.isAnnotationPresent(annotationType); - case VIEW: - return annotationType.equals(ViewScoped.class) ? true : delegate.isAnnotationPresent(annotationType); - default: - return delegate.isAnnotationPresent(annotationType); + public Set> getFields() { + return delegate.getFields(); + } + + public Set getAnnotations() { + initialize(); + + if (annotations==null){ + HashSet myAnnotations = new HashSet(); + myAnnotations.addAll(delegate.getAnnotations()); + if (scopedLiteral!=null && !myAnnotations.contains(scopedLiteral)){ + myAnnotations.add(scopedLiteral); } + + annotations = Collections.unmodifiableSet(myAnnotations); } - }; - - event.setAnnotatedType(wrapper); - } - } - - public void configureBean(ProcessBean event , BeanManager manager){ - Class beanScope = event.getBean().getScope(); - System.out.println(beanScope.toString()); + + return annotations; + } + + public boolean isAnnotationPresent(Class annotationType) { + if (expectedScopedAnnotationType!=null && expectedScopedAnnotationType.isAssignableFrom(annotationType)){ + return true; + } + else{ + return delegate.isAnnotationPresent(annotationType); + } + } + }; + + event.setAnnotatedType(newType); } private EntityManagerScope getConfiguredEntityManagerScope() { - if (selectedScope==null){ - EntityManagerScope entityManagerScope = null; - URL configURL = getClass().getResource("demoiselle.properties"); - - if (configURL != null) { - try { - org.apache.commons.configuration.Configuration config = new PropertiesConfiguration( - configURL); - Configuration configAnnotation = EntityManagerConfig.class - .getAnnotation(Configuration.class); - Name nameAnnotation = EntityManagerConfig.class.getDeclaredField("entityManagerScope") - .getAnnotation(Name.class); - - String prefix = configAnnotation.prefix(); - String sufix = nameAnnotation.value(); - - String property = prefix.endsWith(".") ? prefix + sufix : prefix + "." + sufix; - - String scopeValue = config.getString(property, EntityManagerScope.REQUEST.name()) - .toUpperCase(); - - for (EntityManagerScope currentScope : EntityManagerScope.values()) { - if (currentScope.name().equals(scopeValue)) { - entityManagerScope = currentScope; - break; - } - } - - if (entityManagerScope == null) { - entityManagerScope = EntityManagerScope.REQUEST; - } - } catch (Exception e) { - getLogger().debug(getBundle().getString("")); - entityManagerScope = EntityManagerScope.REQUEST; + EntityManagerScope entityManagerScope = null; + + try { + org.apache.commons.configuration.Configuration config = new PropertiesConfiguration(DEMOISELLE_PROPERTIES_FILE_NAME); + Configuration configAnnotation = EntityManagerConfig.class.getAnnotation(Configuration.class); + Name nameAnnotation = EntityManagerConfig.class.getDeclaredField("entityManagerScope").getAnnotation( + Name.class); + + String prefix = configAnnotation.prefix(); + String sufix = nameAnnotation.value(); + + String property = prefix.endsWith(".") ? prefix + sufix : prefix + "." + sufix; + + String scopeValue = config.getString(property, EntityManagerScope.REQUEST.name()).toUpperCase(); + + for (EntityManagerScope currentScope : EntityManagerScope.values()) { + if (currentScope.name().equals(scopeValue)) { + entityManagerScope = currentScope; + getLogger().info(getBundle().getString("defining-entity-manager-scope",entityManagerScope.name())); + break; } } - else{ + + if (entityManagerScope == null) { + getLogger().info(getBundle().getString("entity-manager-scope-not-defined",EntityManagerScope.REQUEST.name())); entityManagerScope = EntityManagerScope.REQUEST; } - - this.selectedScope = entityManagerScope; + } catch (ConfigurationException e) { + getLogger().info(getBundle().getString("entity-manager-scope-not-defined",EntityManagerScope.REQUEST.name())); + entityManagerScope = EntityManagerScope.REQUEST; + } catch (Exception e){ + throw new DemoiselleException(e); } - return selectedScope; + return entityManagerScope; } private Logger getLogger() { @@ -194,9 +240,15 @@ public class EntityManagerBootstrap implements Extension { private ResourceBundle getBundle() { if (bundle == null) { - bundle = new ResourceBundle("demoiselle-jpa-bundle.properties", Locale.getDefault()); + bundle = new ResourceBundle("demoiselle-jpa-bundle", Locale.getDefault()); } return bundle; } + + class RequestLiteral extends AnnotationLiteral implements RequestScoped{private static final long serialVersionUID = 1L;} + class SessionLiteral extends AnnotationLiteral implements SessionScoped{private static final long serialVersionUID = 1L;} + class ApplicationLiteral extends AnnotationLiteral implements ApplicationScoped{private static final long serialVersionUID = 1L;} + class ViewLiteral extends AnnotationLiteral implements ViewScoped{private static final long serialVersionUID = 1L;} + class ConversationLiteral extends AnnotationLiteral implements ConversationScoped{private static final long serialVersionUID = 1L;} } diff --git a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/EntityManagerConfig.java b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/EntityManagerConfig.java index d103b0c..7b9eb12 100644 --- a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/EntityManagerConfig.java +++ b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/configuration/EntityManagerConfig.java @@ -50,7 +50,7 @@ import br.gov.frameworkdemoiselle.util.Strings; /** * Configuration class responsible for retrieving specific entity manager parameter values from properties file. */ -@Configuration(prefix = "frameworkdemoiselle.persistence.") +@Configuration(prefix = "frameworkdemoiselle.persistence") public class EntityManagerConfig implements Serializable { private static final long serialVersionUID = 1L; diff --git a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerProducer.java b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerProducer.java index ca1a6c2..8d6e84b 100644 --- a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerProducer.java +++ b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerProducer.java @@ -44,7 +44,6 @@ import java.util.Set; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; -import javax.enterprise.context.RequestScoped; import javax.enterprise.inject.Default; import javax.enterprise.inject.Produces; import javax.enterprise.inject.spi.InjectionPoint; @@ -67,8 +66,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle; * persistence.xml, demoiselle.properties or @PersistenceUnit annotation. *

*/ -@RequestScoped -public class EntityManagerProducer implements Serializable { +public class EntityManagerProducer implements Serializable{ private static final long serialVersionUID = 1L; @@ -83,7 +81,7 @@ public class EntityManagerProducer implements Serializable { @Inject private EntityManagerFactoryProducer factory; - + /** *

* Default EntityManager factory. Tries two strategies to produces EntityManager instances. @@ -98,7 +96,7 @@ public class EntityManagerProducer implements Serializable { */ @Default @Produces - public EntityManager createDefault(InjectionPoint ip, EntityManagerConfig config) { + protected EntityManager createDefault(InjectionPoint ip, EntityManagerConfig config) { String persistenceUnit = getFromProperties(config); if (persistenceUnit == null) { @@ -108,9 +106,21 @@ public class EntityManagerProducer implements Serializable { return new EntityManagerProxy(persistenceUnit); } + /** + * + *

+ * Factory that reads the {@link Name} qualifier and creates an entity manager with + * a matching persistence unit name. + *

+ * + * + * @param config + * Suplies informations about EntityManager defined in properties file. + * @return Produced EntityManager. + */ @Name("") @Produces - public EntityManager createNamed(InjectionPoint ip, EntityManagerConfig config) { + protected EntityManager createNamed(InjectionPoint ip, EntityManagerConfig config) { String persistenceUnit = ip.getAnnotated().getAnnotation(Name.class).value(); return new EntityManagerProxy(persistenceUnit); } @@ -166,16 +176,16 @@ public class EntityManagerProducer implements Serializable { return persistenceUnits.iterator().next(); } } - + @PostConstruct - public void init() { + protected void init() { for (String persistenceUnit : factory.getCache().keySet()) { getEntityManager(persistenceUnit); } } @PreDestroy - public void close() { + protected void close() { for (EntityManager entityManager : cache.values()) { entityManager.close(); } diff --git a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/RequestScopedProducer.java b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/RequestScopedProducer.java deleted file mode 100644 index 94ca895..0000000 --- a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/RequestScopedProducer.java +++ /dev/null @@ -1,20 +0,0 @@ -package br.gov.frameworkdemoiselle.internal.producer; - -import static java.lang.annotation.ElementType.TYPE; -import static java.lang.annotation.RetentionPolicy.RUNTIME; - -import java.lang.annotation.Inherited; -import java.lang.annotation.Retention; -import java.lang.annotation.Target; - -import javax.enterprise.context.RequestScoped; -import javax.enterprise.inject.Stereotype; - -@RequestScoped -@Stereotype -@Inherited -@Retention(RUNTIME) -@Target({ TYPE }) -public @interface RequestScopedProducer { - -} diff --git a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/proxy/EntityManagerProxy.java b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/proxy/EntityManagerProxy.java index e2429f4..e6ae130 100644 --- a/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/proxy/EntityManagerProxy.java +++ b/impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/proxy/EntityManagerProxy.java @@ -51,8 +51,15 @@ import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.metamodel.Metamodel; +import org.slf4j.Logger; + +import br.gov.frameworkdemoiselle.DemoiselleException; +import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig; +import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope; import br.gov.frameworkdemoiselle.internal.producer.EntityManagerProducer; import br.gov.frameworkdemoiselle.util.Beans; +import br.gov.frameworkdemoiselle.util.NameQualifier; +import br.gov.frameworkdemoiselle.util.ResourceBundle; /** * Delegates all operation invocations to the cached EntityManager. @@ -62,7 +69,7 @@ import br.gov.frameworkdemoiselle.util.Beans; public class EntityManagerProxy implements EntityManager, Serializable { private static final long serialVersionUID = 1L; - + /** * Persistence unit of the delegated EntityManager. */ @@ -95,6 +102,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @Override public void persist(Object entity) { joinTransactionIfNecessary(); + checkEntityManagerScopePassivable(entity); getEntityManagerDelegate().persist(entity); } @@ -105,6 +113,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @Override public T merge(T entity) { joinTransactionIfNecessary(); + checkEntityManagerScopePassivable(entity); return getEntityManagerDelegate().merge(entity); } @@ -115,6 +124,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { @Override public void remove(Object entity) { joinTransactionIfNecessary(); + checkEntityManagerScopePassivable(entity); getEntityManagerDelegate().remove(entity); } @@ -510,4 +520,30 @@ public class EntityManagerProxy implements EntityManager, Serializable { public String toString() { return getEntityManagerDelegate().toString(); } + + public EntityManagerConfig getConfiguration() { + return Beans.getReference(EntityManagerConfig.class); + } + + public Logger getLogger() { + return Beans.getReference(Logger.class); + } + + public ResourceBundle getBundle(){ + return Beans.getReference(ResourceBundle.class,new NameQualifier("demoiselle-jpa-bundle")); + } + + private void checkEntityManagerScopePassivable(Object entity) { + EntityManagerConfig configuration = getConfiguration(); + if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION + || configuration.getEntityManagerScope()==EntityManagerScope.SESSION + || configuration.getEntityManagerScope()==EntityManagerScope.VIEW){ + LockModeType lockMode = getEntityManagerDelegate().getLockMode(entity); + if (lockMode != LockModeType.OPTIMISTIC_FORCE_INCREMENT && lockMode != LockModeType.WRITE){ + String message = getBundle().getString("passivable-scope-with-pessimistic-lock" , configuration.getEntityManagerScope().toString()); + getLogger().error(message); + throw new DemoiselleException(message); + } + } + } } 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 96a807f..1efa832 100644 --- a/impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties +++ b/impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties @@ -42,6 +42,9 @@ can-not-get-persistence-unit-from-persistence=N\u00E3o foi poss\u00EDvel obter a more-than-one-persistence-unit-defined=Existe mais de uma unidade de persist\u00EAncia definida. Utilize @{0} no ponto de inje\u00E7\u00E3o ou defina o atributo "frameworkdemoiselle.persistence.unit.name" no arquivo demoiselle.properties. persistence-unit-name-found=Unidade de persist\u00EAncia "{0}" encontrada. entity-manager-closed=O gerenciador de entidades foi fechado. -no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a configura\u00E7\u00E3o "{0}" no arquivo "{1}" e defina a sua estrat\u00E9gia de transa\u00E7\u00E3o. +no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a configura\u00E7\u00E3o "{0}" no arquivo "{1}" e defina a sua estrat\u00E9gia de transa\u00E7\u00E3o. malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados. invalid-scope-for-entity-manager=O escopo especificado para o Entity Manager \u00E9 inv\u00E1lido. Por favor informe um dos escopos v\u00E1lidos para a propriedade frameworkdemoiselle.persistence.entitymanager.scope\: request, session, view, conversation, application +entity-manager-scope-not-defined=N\u00E3o foi poss\u00EDvel ler o escopo configurado para o Entity Manager, usando o escopo padr\u00E3o [{0}] +passivable-scope-with-pessimistic-lock=Entity Manager armazenado no escopo [{0}] requer o uso de trava otimista com vers\u00E3o (veja [LockModeType.OPTIMISTIC_FORCE_INCREMENT]) +defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager \ No newline at end of file diff --git a/impl/extension/jpa/src/test/java/producer/ProducerTest.java b/impl/extension/jpa/src/test/java/producer/ProducerTest.java index b0c7f73..8750eb1 100644 --- a/impl/extension/jpa/src/test/java/producer/ProducerTest.java +++ b/impl/extension/jpa/src/test/java/producer/ProducerTest.java @@ -7,12 +7,16 @@ import static org.junit.Assert.assertTrue; import javax.persistence.EntityManager; import org.jboss.arquillian.container.test.api.Deployment; +import org.jboss.arquillian.container.test.api.OperateOnDeployment; import org.jboss.arquillian.junit.Arquillian; import org.jboss.shrinkwrap.api.spec.WebArchive; +import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import test.Tests; +import br.gov.frameworkdemoiselle.context.RequestContext; import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy; import br.gov.frameworkdemoiselle.util.Beans; import br.gov.frameworkdemoiselle.util.NameQualifier; @@ -22,16 +26,38 @@ public class ProducerTest { private static final String PATH = "src/test/resources/producer"; - @Deployment + @Deployment(name="request_scoped_producer") public static WebArchive createDeployment() { WebArchive deployment = Tests.createDeployment(ProducerTest.class); deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml"); deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle.properties"), "demoiselle.properties"); - + + return deployment; + } + + @Deployment(name="no_scoped_producer") + public static WebArchive createNoScopedDeployment() { + WebArchive deployment = Tests.createDeployment(ProducerTest.class); + deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml"); + deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle_noscoped.properties"), "demoiselle.properties"); + return deployment; } + + @Before + public void before(){ + RequestContext ctx = Beans.getReference(RequestContext.class); + ctx.activate(); + } + + @After + public void after(){ + RequestContext ctx = Beans.getReference(RequestContext.class); + ctx.deactivate(); + } @Test + @OperateOnDeployment("request_scoped_producer") public void produceEntityManager() { EntityManager manager = Beans.getReference(EntityManager.class); @@ -40,6 +66,7 @@ public class ProducerTest { } @Test + @OperateOnDeployment("request_scoped_producer") public void produceMultipleEntityManagers() { EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); @@ -53,6 +80,7 @@ public class ProducerTest { } @Test + @OperateOnDeployment("request_scoped_producer") public void produceOneEntityManagerPerRequest() { EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); @@ -71,6 +99,29 @@ public class ProducerTest { assertTrue(m2.contains(entity)); } + + @Test + @OperateOnDeployment("no_scoped_producer") + public void produceOneEntityManagerPerInjection() { + //Testa se ao usar o produtor sem escopo, mais de um entity manager é criado a cada injeção. + + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); + + assertNotNull(m1); + assertEquals(EntityManagerProxy.class, m1.getClass()); + + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); + + assertNotNull(m2); + assertEquals(EntityManagerProxy.class, m2.getClass()); + + MyEntity entity = new MyEntity(); + entity.setId(createId("testID")); + + m1.persist(entity); + + assertTrue( ! m2.contains(entity)); + } private String createId(String id) { return this.getClass().getName() + "_" + id; diff --git a/impl/extension/jpa/src/test/resources/producer/demoiselle.properties b/impl/extension/jpa/src/test/resources/producer/demoiselle.properties index 6516d47..68147ca 100644 --- a/impl/extension/jpa/src/test/resources/producer/demoiselle.properties +++ b/impl/extension/jpa/src/test/resources/producer/demoiselle.properties @@ -1 +1,2 @@ -frameworkdemoiselle.persistence.default.unit.name=pu \ No newline at end of file +frameworkdemoiselle.persistence.default.unit.name=pu +frameworkdemoiselle.persistence.entitymanager.scope=request \ No newline at end of file diff --git a/impl/extension/jpa/src/test/resources/producer/demoiselle_noscoped.properties b/impl/extension/jpa/src/test/resources/producer/demoiselle_noscoped.properties new file mode 100644 index 0000000..5c6ecae --- /dev/null +++ b/impl/extension/jpa/src/test/resources/producer/demoiselle_noscoped.properties @@ -0,0 +1,2 @@ +frameworkdemoiselle.persistence.default.unit.name=pu +frameworkdemoiselle.persistence.entitymanager.scope=noscope \ No newline at end of file -- libgit2 0.21.2