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 extends Annotation> scopedLiteral;
+ private Class extends Annotation> 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 extends Annotation> 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 extends Annotation> beanScope = event.getBean().getScope();
- System.out.println(beanScope.toString());
+
+ return annotations;
+ }
+
+ public boolean isAnnotationPresent(Class extends Annotation> 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