Commit 1a85fed145b24aff40e9550a0f930e9ff5642c31
Exists in
master
Merge branch '2.4.0' of git@github.com:demoiselle/framework.git into 2.4.0
Showing
21 changed files
with
963 additions
and
444 deletions
Show diff stats
impl/core/src/main/java/br/gov/frameworkdemoiselle/annotation/ViewScoped.java
| @@ -55,7 +55,7 @@ import javax.enterprise.context.NormalScope; | @@ -55,7 +55,7 @@ import javax.enterprise.context.NormalScope; | ||
| 55 | @Inherited | 55 | @Inherited |
| 56 | @Target({ METHOD, TYPE, FIELD }) | 56 | @Target({ METHOD, TYPE, FIELD }) |
| 57 | @Retention(RUNTIME) | 57 | @Retention(RUNTIME) |
| 58 | -@NormalScope | 58 | +@NormalScope(passivating=true) |
| 59 | public @interface ViewScoped { | 59 | public @interface ViewScoped { |
| 60 | 60 | ||
| 61 | } | 61 | } |
impl/core/src/main/java/br/gov/frameworkdemoiselle/util/Beans.java
| @@ -40,10 +40,7 @@ import java.lang.annotation.Annotation; | @@ -40,10 +40,7 @@ import java.lang.annotation.Annotation; | ||
| 40 | import java.lang.reflect.Member; | 40 | import java.lang.reflect.Member; |
| 41 | import java.lang.reflect.Type; | 41 | import java.lang.reflect.Type; |
| 42 | import java.util.Arrays; | 42 | import java.util.Arrays; |
| 43 | -import java.util.Collections; | ||
| 44 | -import java.util.HashMap; | ||
| 45 | import java.util.HashSet; | 43 | import java.util.HashSet; |
| 46 | -import java.util.Map; | ||
| 47 | import java.util.NoSuchElementException; | 44 | import java.util.NoSuchElementException; |
| 48 | import java.util.Set; | 45 | import java.util.Set; |
| 49 | 46 | ||
| @@ -66,24 +63,19 @@ import br.gov.frameworkdemoiselle.DemoiselleException; | @@ -66,24 +63,19 @@ import br.gov.frameworkdemoiselle.DemoiselleException; | ||
| 66 | */ | 63 | */ |
| 67 | public final class Beans { | 64 | public final class Beans { |
| 68 | 65 | ||
| 69 | - private static final Map<ClassLoader, BeanManager> beanManagerCache = Collections | ||
| 70 | - .synchronizedMap(new HashMap<ClassLoader, BeanManager>()); | ||
| 71 | - | 66 | + private static BeanManager beanManager = null; |
| 67 | + | ||
| 72 | private Beans() { | 68 | private Beans() { |
| 73 | } | 69 | } |
| 74 | 70 | ||
| 75 | - public static void setBeanManager(BeanManager beanManager) { | ||
| 76 | - beanManagerCache.put(getCurrentClassLoader(), beanManager); | 71 | + public static void setBeanManager(BeanManager manager) { |
| 72 | + beanManager = manager; | ||
| 77 | } | 73 | } |
| 78 | 74 | ||
| 79 | public static BeanManager getBeanManager() { | 75 | public static BeanManager getBeanManager() { |
| 80 | - return beanManagerCache.get(getCurrentClassLoader()); | ||
| 81 | - } | ||
| 82 | - | ||
| 83 | - private static ClassLoader getCurrentClassLoader() { | ||
| 84 | - return Thread.currentThread().getContextClassLoader(); | 76 | + return beanManager; |
| 85 | } | 77 | } |
| 86 | - | 78 | + |
| 87 | /** | 79 | /** |
| 88 | * Obtains a injectble instance of a bean, which have the given required type and qualifiers, and are available for | 80 | * Obtains a injectble instance of a bean, which have the given required type and qualifiers, and are available for |
| 89 | * injection in the point where this method was call. | 81 | * injection in the point where this method was call. |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/bootstrap/EntityManagerBootstrap.java
| @@ -1,254 +0,0 @@ | @@ -1,254 +0,0 @@ | ||
| 1 | -/* | ||
| 2 | - * Demoiselle Framework | ||
| 3 | - * Copyright (C) 2010 SERPRO | ||
| 4 | - * ---------------------------------------------------------------------------- | ||
| 5 | - * This file is part of Demoiselle Framework. | ||
| 6 | - * | ||
| 7 | - * Demoiselle Framework is free software; you can redistribute it and/or | ||
| 8 | - * modify it under the terms of the GNU Lesser General Public License version 3 | ||
| 9 | - * as published by the Free Software Foundation. | ||
| 10 | - * | ||
| 11 | - * This program is distributed in the hope that it will be useful, | ||
| 12 | - * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | - * GNU General Public License for more details. | ||
| 15 | - * | ||
| 16 | - * You should have received a copy of the GNU Lesser General Public License version 3 | ||
| 17 | - * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
| 18 | - * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | - * Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | - * ---------------------------------------------------------------------------- | ||
| 21 | - * Este arquivo é parte do Framework Demoiselle. | ||
| 22 | - * | ||
| 23 | - * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
| 24 | - * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
| 25 | - * do Software Livre (FSF). | ||
| 26 | - * | ||
| 27 | - * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
| 28 | - * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
| 29 | - * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
| 30 | - * para maiores detalhes. | ||
| 31 | - * | ||
| 32 | - * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
| 33 | - * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
| 34 | - * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
| 35 | - * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
| 36 | - */ | ||
| 37 | -package br.gov.frameworkdemoiselle.internal.bootstrap; | ||
| 38 | - | ||
| 39 | -import java.lang.annotation.Annotation; | ||
| 40 | -import java.lang.reflect.Type; | ||
| 41 | -import java.util.Collections; | ||
| 42 | -import java.util.HashSet; | ||
| 43 | -import java.util.Locale; | ||
| 44 | -import java.util.Set; | ||
| 45 | - | ||
| 46 | -import javax.enterprise.context.ApplicationScoped; | ||
| 47 | -import javax.enterprise.context.ConversationScoped; | ||
| 48 | -import javax.enterprise.context.RequestScoped; | ||
| 49 | -import javax.enterprise.context.SessionScoped; | ||
| 50 | -import javax.enterprise.event.Observes; | ||
| 51 | -import javax.enterprise.inject.spi.AnnotatedConstructor; | ||
| 52 | -import javax.enterprise.inject.spi.AnnotatedField; | ||
| 53 | -import javax.enterprise.inject.spi.AnnotatedMethod; | ||
| 54 | -import javax.enterprise.inject.spi.AnnotatedType; | ||
| 55 | -import javax.enterprise.inject.spi.Extension; | ||
| 56 | -import javax.enterprise.inject.spi.ProcessAnnotatedType; | ||
| 57 | -import javax.enterprise.util.AnnotationLiteral; | ||
| 58 | - | ||
| 59 | -import org.apache.commons.configuration.ConfigurationException; | ||
| 60 | -import org.apache.commons.configuration.PropertiesConfiguration; | ||
| 61 | -import org.slf4j.Logger; | ||
| 62 | - | ||
| 63 | -import br.gov.frameworkdemoiselle.DemoiselleException; | ||
| 64 | -import br.gov.frameworkdemoiselle.annotation.Name; | ||
| 65 | -import br.gov.frameworkdemoiselle.annotation.ViewScoped; | ||
| 66 | -import br.gov.frameworkdemoiselle.configuration.Configuration; | ||
| 67 | -import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig; | ||
| 68 | -import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope; | ||
| 69 | -import br.gov.frameworkdemoiselle.internal.producer.EntityManagerProducer; | ||
| 70 | -import br.gov.frameworkdemoiselle.internal.producer.LoggerProducer; | ||
| 71 | -import br.gov.frameworkdemoiselle.util.ResourceBundle; | ||
| 72 | - | ||
| 73 | -public class EntityManagerBootstrap implements Extension { | ||
| 74 | - | ||
| 75 | - private Logger logger; | ||
| 76 | - | ||
| 77 | - private transient ResourceBundle bundle; | ||
| 78 | - | ||
| 79 | - private static final String DEMOISELLE_PROPERTIES_FILE_NAME = "demoiselle.properties"; | ||
| 80 | - | ||
| 81 | - public void makeScoped(@Observes ProcessAnnotatedType<EntityManagerProducer> event){ | ||
| 82 | - final AnnotatedType<EntityManagerProducer> type = event.getAnnotatedType(); | ||
| 83 | - final EntityManagerScope scope = getConfiguredEntityManagerScope(); | ||
| 84 | - | ||
| 85 | - AnnotatedType<EntityManagerProducer> newType = new AnnotatedType<EntityManagerProducer>() { | ||
| 86 | - | ||
| 87 | - private AnnotatedType<EntityManagerProducer> delegate = type; | ||
| 88 | - private AnnotationLiteral<? extends Annotation> scopedLiteral; | ||
| 89 | - private Class<? extends Annotation> expectedScopedAnnotationType; | ||
| 90 | - private boolean initialized = false; | ||
| 91 | - private Set<Annotation> annotations; | ||
| 92 | - | ||
| 93 | - private void initialize(){ | ||
| 94 | - if (!initialized){ | ||
| 95 | - switch (scope) { | ||
| 96 | - case APPLICATION: | ||
| 97 | - expectedScopedAnnotationType = ApplicationScoped.class; | ||
| 98 | - scopedLiteral = new ApplicationLiteral(); | ||
| 99 | - break; | ||
| 100 | - case CONVERSATION: | ||
| 101 | - expectedScopedAnnotationType = ConversationScoped.class; | ||
| 102 | - scopedLiteral = new ConversationLiteral(); | ||
| 103 | - break; | ||
| 104 | - case NOSCOPE: | ||
| 105 | - expectedScopedAnnotationType = null; | ||
| 106 | - scopedLiteral = null; | ||
| 107 | - break; | ||
| 108 | - case REQUEST: | ||
| 109 | - expectedScopedAnnotationType = RequestScoped.class; | ||
| 110 | - scopedLiteral = new RequestLiteral(); | ||
| 111 | - break; | ||
| 112 | - case SESSION: | ||
| 113 | - expectedScopedAnnotationType = SessionScoped.class; | ||
| 114 | - scopedLiteral = new SessionLiteral(); | ||
| 115 | - break; | ||
| 116 | - case VIEW: | ||
| 117 | - expectedScopedAnnotationType = ViewScoped.class; | ||
| 118 | - scopedLiteral = new ViewLiteral(); | ||
| 119 | - break; | ||
| 120 | - default: | ||
| 121 | - expectedScopedAnnotationType = null; | ||
| 122 | - scopedLiteral = null; | ||
| 123 | - break; | ||
| 124 | - } | ||
| 125 | - | ||
| 126 | - initialized = true; | ||
| 127 | - } | ||
| 128 | - } | ||
| 129 | - | ||
| 130 | - public Class<EntityManagerProducer> getJavaClass() { | ||
| 131 | - return delegate.getJavaClass(); | ||
| 132 | - } | ||
| 133 | - | ||
| 134 | - public Type getBaseType() { | ||
| 135 | - return delegate.getBaseType(); | ||
| 136 | - } | ||
| 137 | - | ||
| 138 | - public Set<AnnotatedConstructor<EntityManagerProducer>> getConstructors() { | ||
| 139 | - return delegate.getConstructors(); | ||
| 140 | - } | ||
| 141 | - | ||
| 142 | - public Set<Type> getTypeClosure() { | ||
| 143 | - return delegate.getTypeClosure(); | ||
| 144 | - } | ||
| 145 | - | ||
| 146 | - public Set<AnnotatedMethod<? super EntityManagerProducer>> getMethods() { | ||
| 147 | - return delegate.getMethods(); | ||
| 148 | - } | ||
| 149 | - | ||
| 150 | - @SuppressWarnings("unchecked") | ||
| 151 | - public <T extends Annotation> T getAnnotation(Class<T> annotationType) { | ||
| 152 | - initialize(); | ||
| 153 | - | ||
| 154 | - if (expectedScopedAnnotationType!=null && expectedScopedAnnotationType.isAssignableFrom(annotationType)){ | ||
| 155 | - return (T) scopedLiteral; | ||
| 156 | - } | ||
| 157 | - else{ | ||
| 158 | - return delegate.getAnnotation(annotationType); | ||
| 159 | - } | ||
| 160 | - } | ||
| 161 | - | ||
| 162 | - public Set<AnnotatedField<? super EntityManagerProducer>> getFields() { | ||
| 163 | - return delegate.getFields(); | ||
| 164 | - } | ||
| 165 | - | ||
| 166 | - public Set<Annotation> getAnnotations() { | ||
| 167 | - initialize(); | ||
| 168 | - | ||
| 169 | - if (annotations==null){ | ||
| 170 | - HashSet<Annotation> myAnnotations = new HashSet<Annotation>(); | ||
| 171 | - myAnnotations.addAll(delegate.getAnnotations()); | ||
| 172 | - if (scopedLiteral!=null && !myAnnotations.contains(scopedLiteral)){ | ||
| 173 | - myAnnotations.add(scopedLiteral); | ||
| 174 | - } | ||
| 175 | - | ||
| 176 | - annotations = Collections.unmodifiableSet(myAnnotations); | ||
| 177 | - } | ||
| 178 | - | ||
| 179 | - return annotations; | ||
| 180 | - } | ||
| 181 | - | ||
| 182 | - public boolean isAnnotationPresent(Class<? extends Annotation> annotationType) { | ||
| 183 | - if (expectedScopedAnnotationType!=null && expectedScopedAnnotationType.isAssignableFrom(annotationType)){ | ||
| 184 | - return true; | ||
| 185 | - } | ||
| 186 | - else{ | ||
| 187 | - return delegate.isAnnotationPresent(annotationType); | ||
| 188 | - } | ||
| 189 | - } | ||
| 190 | - }; | ||
| 191 | - | ||
| 192 | - event.setAnnotatedType(newType); | ||
| 193 | - } | ||
| 194 | - | ||
| 195 | - private EntityManagerScope getConfiguredEntityManagerScope() { | ||
| 196 | - EntityManagerScope entityManagerScope = null; | ||
| 197 | - | ||
| 198 | - try { | ||
| 199 | - org.apache.commons.configuration.Configuration config = new PropertiesConfiguration(DEMOISELLE_PROPERTIES_FILE_NAME); | ||
| 200 | - Configuration configAnnotation = EntityManagerConfig.class.getAnnotation(Configuration.class); | ||
| 201 | - Name nameAnnotation = EntityManagerConfig.class.getDeclaredField("entityManagerScope").getAnnotation( | ||
| 202 | - Name.class); | ||
| 203 | - | ||
| 204 | - String prefix = configAnnotation.prefix(); | ||
| 205 | - String sufix = nameAnnotation.value(); | ||
| 206 | - | ||
| 207 | - String property = prefix.endsWith(".") ? prefix + sufix : prefix + "." + sufix; | ||
| 208 | - | ||
| 209 | - String scopeValue = config.getString(property, EntityManagerScope.REQUEST.name()).toUpperCase(); | ||
| 210 | - | ||
| 211 | - for (EntityManagerScope currentScope : EntityManagerScope.values()) { | ||
| 212 | - if (currentScope.name().equals(scopeValue)) { | ||
| 213 | - entityManagerScope = currentScope; | ||
| 214 | - getLogger().info(getBundle().getString("defining-entity-manager-scope",entityManagerScope.name())); | ||
| 215 | - break; | ||
| 216 | - } | ||
| 217 | - } | ||
| 218 | - | ||
| 219 | - if (entityManagerScope == null) { | ||
| 220 | - getLogger().info(getBundle().getString("entity-manager-scope-not-defined",EntityManagerScope.REQUEST.name())); | ||
| 221 | - entityManagerScope = EntityManagerScope.REQUEST; | ||
| 222 | - } | ||
| 223 | - } catch (ConfigurationException e) { | ||
| 224 | - getLogger().info(getBundle().getString("entity-manager-scope-not-defined",EntityManagerScope.REQUEST.name())); | ||
| 225 | - entityManagerScope = EntityManagerScope.REQUEST; | ||
| 226 | - } catch (Exception e){ | ||
| 227 | - throw new DemoiselleException(e); | ||
| 228 | - } | ||
| 229 | - | ||
| 230 | - return entityManagerScope; | ||
| 231 | - } | ||
| 232 | - | ||
| 233 | - private Logger getLogger() { | ||
| 234 | - if (logger == null) { | ||
| 235 | - logger = LoggerProducer.create(EntityManagerBootstrap.class); | ||
| 236 | - } | ||
| 237 | - | ||
| 238 | - return logger; | ||
| 239 | - } | ||
| 240 | - | ||
| 241 | - private ResourceBundle getBundle() { | ||
| 242 | - if (bundle == null) { | ||
| 243 | - bundle = new ResourceBundle("demoiselle-jpa-bundle", Locale.getDefault()); | ||
| 244 | - } | ||
| 245 | - | ||
| 246 | - return bundle; | ||
| 247 | - } | ||
| 248 | - | ||
| 249 | - class RequestLiteral extends AnnotationLiteral<RequestScoped> implements RequestScoped{private static final long serialVersionUID = 1L;} | ||
| 250 | - class SessionLiteral extends AnnotationLiteral<SessionScoped> implements SessionScoped{private static final long serialVersionUID = 1L;} | ||
| 251 | - class ApplicationLiteral extends AnnotationLiteral<ApplicationScoped> implements ApplicationScoped{private static final long serialVersionUID = 1L;} | ||
| 252 | - class ViewLiteral extends AnnotationLiteral<ViewScoped> implements ViewScoped{private static final long serialVersionUID = 1L;} | ||
| 253 | - class ConversationLiteral extends AnnotationLiteral<ConversationScoped> implements ConversationScoped{private static final long serialVersionUID = 1L;} | ||
| 254 | -} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/AbstractEntityManagerStore.java
0 → 100644
| @@ -0,0 +1,153 @@ | @@ -0,0 +1,153 @@ | ||
| 1 | +/* | ||
| 2 | + * Demoiselle Framework | ||
| 3 | + * Copyright (C) 2010 SERPRO | ||
| 4 | + * ---------------------------------------------------------------------------- | ||
| 5 | + * This file is part of Demoiselle Framework. | ||
| 6 | + * | ||
| 7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
| 8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
| 9 | + * as published by the Free Software Foundation. | ||
| 10 | + * | ||
| 11 | + * This program is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | + * GNU General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
| 17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
| 18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | + * ---------------------------------------------------------------------------- | ||
| 21 | + * Este arquivo é parte do Framework Demoiselle. | ||
| 22 | + * | ||
| 23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
| 24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
| 25 | + * do Software Livre (FSF). | ||
| 26 | + * | ||
| 27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
| 28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
| 29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
| 30 | + * para maiores detalhes. | ||
| 31 | + * | ||
| 32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
| 33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
| 34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
| 35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
| 36 | + */ | ||
| 37 | +package br.gov.frameworkdemoiselle.internal.producer; | ||
| 38 | + | ||
| 39 | +import java.util.Collections; | ||
| 40 | +import java.util.HashMap; | ||
| 41 | +import java.util.Map; | ||
| 42 | + | ||
| 43 | +import javax.enterprise.context.RequestScoped; | ||
| 44 | +import javax.inject.Inject; | ||
| 45 | +import javax.persistence.EntityManager; | ||
| 46 | +import javax.persistence.FlushModeType; | ||
| 47 | + | ||
| 48 | +import org.slf4j.Logger; | ||
| 49 | + | ||
| 50 | +import br.gov.frameworkdemoiselle.annotation.Name; | ||
| 51 | +import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig; | ||
| 52 | +import br.gov.frameworkdemoiselle.internal.configuration.EntityManagerConfig.EntityManagerScope; | ||
| 53 | +import br.gov.frameworkdemoiselle.util.Beans; | ||
| 54 | +import br.gov.frameworkdemoiselle.util.NameQualifier; | ||
| 55 | +import br.gov.frameworkdemoiselle.util.ResourceBundle; | ||
| 56 | + | ||
| 57 | +/** | ||
| 58 | + * | ||
| 59 | + * <p>Stores produced entity managers. When the {@link EntityManagerProducer} try to create an entity manager it will | ||
| 60 | + * seach this store for a cached instance, only creating a new instance if this cache doesn't contain a suitable one.</p> | ||
| 61 | + * | ||
| 62 | + * <p>There are several concrete implementations of this class, each one corresponding to a scoped cache (ex: {@link RequestEntityManagerStore} | ||
| 63 | + * stores Entity Managers on the request scope). To select witch implementation is used (and with that, what scope is used to store Entity Managers) | ||
| 64 | + * open the "demoiselle.properties" file and edit the property "frameworkdemoiselle.persistence.entitymanager.scope". The default scope is the | ||
| 65 | + * {@link RequestScoped}.</p> | ||
| 66 | + * | ||
| 67 | + * | ||
| 68 | + * @author serpro | ||
| 69 | + * | ||
| 70 | + */ | ||
| 71 | +public abstract class AbstractEntityManagerStore implements EntityManagerStore { | ||
| 72 | + | ||
| 73 | + private static final long serialVersionUID = 1L; | ||
| 74 | + | ||
| 75 | + private final Map<String, EntityManager> cache = Collections.synchronizedMap(new HashMap<String, EntityManager>()); | ||
| 76 | + | ||
| 77 | + @Inject | ||
| 78 | + private EntityManagerFactoryProducer factory; | ||
| 79 | + | ||
| 80 | + @Inject | ||
| 81 | + private Logger logger; | ||
| 82 | + | ||
| 83 | + @Inject | ||
| 84 | + @Name("demoiselle-jpa-bundle") | ||
| 85 | + private ResourceBundle bundle; | ||
| 86 | + | ||
| 87 | + @Inject | ||
| 88 | + private EntityManagerConfig configuration; | ||
| 89 | + | ||
| 90 | + public EntityManager getEntityManager(String persistenceUnit) { | ||
| 91 | + EntityManager entityManager = null; | ||
| 92 | + | ||
| 93 | + if (cache.containsKey(persistenceUnit)) { | ||
| 94 | + entityManager = cache.get(persistenceUnit); | ||
| 95 | + | ||
| 96 | + } else { | ||
| 97 | + entityManager = getFactory().create(persistenceUnit).createEntityManager(); | ||
| 98 | + entityManager.setFlushMode(FlushModeType.AUTO); | ||
| 99 | + | ||
| 100 | + cache.put(persistenceUnit, entityManager); | ||
| 101 | + this.getLogger().info(getBundle().getString("entity-manager-was-created", persistenceUnit)); | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + return entityManager; | ||
| 105 | + } | ||
| 106 | + | ||
| 107 | + void init() { | ||
| 108 | + for (String persistenceUnit : getFactory().getCache().keySet()) { | ||
| 109 | + getEntityManager(persistenceUnit); | ||
| 110 | + } | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + void close() { | ||
| 114 | + //Se o produtor não possui escopo, então o ciclo de vida | ||
| 115 | + //de EntityManager produzidos é responsabilidade do desenvolvedor. Não | ||
| 116 | + //fechamos os EntityManagers aqui. | ||
| 117 | + if (configuration.getEntityManagerScope() != EntityManagerScope.NOSCOPE){ | ||
| 118 | + for (EntityManager entityManager : cache.values()) { | ||
| 119 | + entityManager.close(); | ||
| 120 | + } | ||
| 121 | + } | ||
| 122 | + cache.clear(); | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + public Map<String, EntityManager> getCache() { | ||
| 126 | + if (cache==null || cache.isEmpty()){ | ||
| 127 | + init(); | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + return cache; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + private EntityManagerFactoryProducer getFactory(){ | ||
| 134 | + if (factory==null){ | ||
| 135 | + factory = Beans.getReference(EntityManagerFactoryProducer.class); | ||
| 136 | + } | ||
| 137 | + return factory; | ||
| 138 | + } | ||
| 139 | + | ||
| 140 | + private Logger getLogger(){ | ||
| 141 | + if (logger==null){ | ||
| 142 | + logger = Beans.getReference(Logger.class); | ||
| 143 | + } | ||
| 144 | + return logger; | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + private ResourceBundle getBundle(){ | ||
| 148 | + if (bundle==null){ | ||
| 149 | + bundle = Beans.getReference(ResourceBundle.class , new NameQualifier("demoiselle-jpa-bundle")); | ||
| 150 | + } | ||
| 151 | + return bundle; | ||
| 152 | + } | ||
| 153 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/ApplicationEntityManagerStore.java
0 → 100644
| @@ -0,0 +1,67 @@ | @@ -0,0 +1,67 @@ | ||
| 1 | +/* | ||
| 2 | + * Demoiselle Framework | ||
| 3 | + * Copyright (C) 2010 SERPRO | ||
| 4 | + * ---------------------------------------------------------------------------- | ||
| 5 | + * This file is part of Demoiselle Framework. | ||
| 6 | + * | ||
| 7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
| 8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
| 9 | + * as published by the Free Software Foundation. | ||
| 10 | + * | ||
| 11 | + * This program is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | + * GNU General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
| 17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
| 18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | + * ---------------------------------------------------------------------------- | ||
| 21 | + * Este arquivo é parte do Framework Demoiselle. | ||
| 22 | + * | ||
| 23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
| 24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
| 25 | + * do Software Livre (FSF). | ||
| 26 | + * | ||
| 27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
| 28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
| 29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
| 30 | + * para maiores detalhes. | ||
| 31 | + * | ||
| 32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
| 33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
| 34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
| 35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
| 36 | + */ | ||
| 37 | +package br.gov.frameworkdemoiselle.internal.producer; | ||
| 38 | + | ||
| 39 | +import javax.annotation.PostConstruct; | ||
| 40 | +import javax.annotation.PreDestroy; | ||
| 41 | +import javax.enterprise.context.ApplicationScoped; | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * | ||
| 45 | + * Implementation that stores produced entity managers on the application scope. | ||
| 46 | + * | ||
| 47 | + * @author serpro | ||
| 48 | + * | ||
| 49 | + */ | ||
| 50 | +@ApplicationScoped | ||
| 51 | +public class ApplicationEntityManagerStore extends AbstractEntityManagerStore { | ||
| 52 | + | ||
| 53 | + private static final long serialVersionUID = 1L; | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + @PostConstruct | ||
| 57 | + public void initialize() { | ||
| 58 | + super.init(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + @Override | ||
| 62 | + @PreDestroy | ||
| 63 | + public void terminate() { | ||
| 64 | + super.close(); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/ConversationEntityManagerStore.java
0 → 100644
| @@ -0,0 +1,79 @@ | @@ -0,0 +1,79 @@ | ||
| 1 | +/* | ||
| 2 | + * Demoiselle Framework | ||
| 3 | + * Copyright (C) 2010 SERPRO | ||
| 4 | + * ---------------------------------------------------------------------------- | ||
| 5 | + * This file is part of Demoiselle Framework. | ||
| 6 | + * | ||
| 7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
| 8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
| 9 | + * as published by the Free Software Foundation. | ||
| 10 | + * | ||
| 11 | + * This program is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | + * GNU General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
| 17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
| 18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | + * ---------------------------------------------------------------------------- | ||
| 21 | + * Este arquivo é parte do Framework Demoiselle. | ||
| 22 | + * | ||
| 23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
| 24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
| 25 | + * do Software Livre (FSF). | ||
| 26 | + * | ||
| 27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
| 28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
| 29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
| 30 | + * para maiores detalhes. | ||
| 31 | + * | ||
| 32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
| 33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
| 34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
| 35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
| 36 | + */ | ||
| 37 | +package br.gov.frameworkdemoiselle.internal.producer; | ||
| 38 | + | ||
| 39 | +import javax.annotation.PostConstruct; | ||
| 40 | +import javax.annotation.PreDestroy; | ||
| 41 | +import javax.enterprise.context.Conversation; | ||
| 42 | +import javax.enterprise.context.ConversationScoped; | ||
| 43 | +import javax.inject.Inject; | ||
| 44 | + | ||
| 45 | +/** | ||
| 46 | + * | ||
| 47 | + * Implementation that stores produced entity managers on the conversation scope. | ||
| 48 | + * It's the user responsibility to start and end conversations injecting the {@link Conversation} object | ||
| 49 | + * inside of a conversation scoped bean that need the entity manager. | ||
| 50 | + * | ||
| 51 | + * @author serpro | ||
| 52 | + * | ||
| 53 | + */ | ||
| 54 | +@ConversationScoped | ||
| 55 | +public class ConversationEntityManagerStore extends AbstractEntityManagerStore { | ||
| 56 | + | ||
| 57 | + private static final long serialVersionUID = 1L; | ||
| 58 | + | ||
| 59 | + @Inject | ||
| 60 | + private Conversation conversation; | ||
| 61 | + | ||
| 62 | + | ||
| 63 | + public Conversation getConversation() { | ||
| 64 | + return conversation; | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | + @Override | ||
| 68 | + @PostConstruct | ||
| 69 | + public void initialize() { | ||
| 70 | + super.init(); | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + @Override | ||
| 74 | + @PreDestroy | ||
| 75 | + public void terminate() { | ||
| 76 | + super.close(); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/DependentEntityManagerStore.java
0 → 100644
| @@ -0,0 +1,68 @@ | @@ -0,0 +1,68 @@ | ||
| 1 | +/* | ||
| 2 | + * Demoiselle Framework | ||
| 3 | + * Copyright (C) 2010 SERPRO | ||
| 4 | + * ---------------------------------------------------------------------------- | ||
| 5 | + * This file is part of Demoiselle Framework. | ||
| 6 | + * | ||
| 7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
| 8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
| 9 | + * as published by the Free Software Foundation. | ||
| 10 | + * | ||
| 11 | + * This program is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | + * GNU General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
| 17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
| 18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | + * ---------------------------------------------------------------------------- | ||
| 21 | + * Este arquivo é parte do Framework Demoiselle. | ||
| 22 | + * | ||
| 23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
| 24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
| 25 | + * do Software Livre (FSF). | ||
| 26 | + * | ||
| 27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
| 28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
| 29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
| 30 | + * para maiores detalhes. | ||
| 31 | + * | ||
| 32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
| 33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
| 34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
| 35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
| 36 | + */ | ||
| 37 | +package br.gov.frameworkdemoiselle.internal.producer; | ||
| 38 | + | ||
| 39 | +import javax.annotation.PostConstruct; | ||
| 40 | +import javax.annotation.PreDestroy; | ||
| 41 | +import javax.enterprise.context.Dependent; | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * | ||
| 45 | + * Implementation that doesn't store entity managers in any scope, instead | ||
| 46 | + * produced entity managers are bound to the duration of the bean that injected them. | ||
| 47 | + * | ||
| 48 | + * @author serpro | ||
| 49 | + * | ||
| 50 | + */ | ||
| 51 | +@Dependent | ||
| 52 | +public class DependentEntityManagerStore extends AbstractEntityManagerStore { | ||
| 53 | + | ||
| 54 | + private static final long serialVersionUID = 1L; | ||
| 55 | + | ||
| 56 | + @Override | ||
| 57 | + @PostConstruct | ||
| 58 | + public void initialize() { | ||
| 59 | + super.init(); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + @Override | ||
| 63 | + @PreDestroy | ||
| 64 | + public void terminate() { | ||
| 65 | + super.close(); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerProducer.java
| @@ -37,19 +37,16 @@ | @@ -37,19 +37,16 @@ | ||
| 37 | package br.gov.frameworkdemoiselle.internal.producer; | 37 | package br.gov.frameworkdemoiselle.internal.producer; |
| 38 | 38 | ||
| 39 | import java.io.Serializable; | 39 | import java.io.Serializable; |
| 40 | -import java.util.Collections; | ||
| 41 | -import java.util.HashMap; | ||
| 42 | import java.util.Map; | 40 | import java.util.Map; |
| 43 | import java.util.Set; | 41 | import java.util.Set; |
| 44 | 42 | ||
| 45 | -import javax.annotation.PostConstruct; | ||
| 46 | -import javax.annotation.PreDestroy; | 43 | +import javax.enterprise.context.ApplicationScoped; |
| 47 | import javax.enterprise.inject.Default; | 44 | import javax.enterprise.inject.Default; |
| 45 | +import javax.enterprise.inject.Instance; | ||
| 48 | import javax.enterprise.inject.Produces; | 46 | import javax.enterprise.inject.Produces; |
| 49 | import javax.enterprise.inject.spi.InjectionPoint; | 47 | import javax.enterprise.inject.spi.InjectionPoint; |
| 50 | import javax.inject.Inject; | 48 | import javax.inject.Inject; |
| 51 | import javax.persistence.EntityManager; | 49 | import javax.persistence.EntityManager; |
| 52 | -import javax.persistence.FlushModeType; | ||
| 53 | 50 | ||
| 54 | import org.slf4j.Logger; | 51 | import org.slf4j.Logger; |
| 55 | 52 | ||
| @@ -66,6 +63,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle; | @@ -66,6 +63,7 @@ import br.gov.frameworkdemoiselle.util.ResourceBundle; | ||
| 66 | * persistence.xml, demoiselle.properties or @PersistenceUnit annotation. | 63 | * persistence.xml, demoiselle.properties or @PersistenceUnit annotation. |
| 67 | * </p> | 64 | * </p> |
| 68 | */ | 65 | */ |
| 66 | +@ApplicationScoped | ||
| 69 | public class EntityManagerProducer implements Serializable{ | 67 | public class EntityManagerProducer implements Serializable{ |
| 70 | 68 | ||
| 71 | private static final long serialVersionUID = 1L; | 69 | private static final long serialVersionUID = 1L; |
| @@ -76,12 +74,16 @@ public class EntityManagerProducer implements Serializable{ | @@ -76,12 +74,16 @@ public class EntityManagerProducer implements Serializable{ | ||
| 76 | @Inject | 74 | @Inject |
| 77 | @Name("demoiselle-jpa-bundle") | 75 | @Name("demoiselle-jpa-bundle") |
| 78 | private ResourceBundle bundle; | 76 | private ResourceBundle bundle; |
| 79 | - | ||
| 80 | - private final Map<String, EntityManager> cache = Collections.synchronizedMap(new HashMap<String, EntityManager>()); | ||
| 81 | - | 77 | + |
| 82 | @Inject | 78 | @Inject |
| 83 | private EntityManagerFactoryProducer factory; | 79 | private EntityManagerFactoryProducer factory; |
| 84 | 80 | ||
| 81 | + @Inject | ||
| 82 | + private Instance<EntityManagerStore> storeInstance; | ||
| 83 | + | ||
| 84 | + @Inject | ||
| 85 | + private EntityManagerConfig configuration; | ||
| 86 | + | ||
| 85 | /** | 87 | /** |
| 86 | * <p> | 88 | * <p> |
| 87 | * Default EntityManager factory. Tries two strategies to produces EntityManager instances. | 89 | * Default EntityManager factory. Tries two strategies to produces EntityManager instances. |
| @@ -125,23 +127,6 @@ public class EntityManagerProducer implements Serializable{ | @@ -125,23 +127,6 @@ public class EntityManagerProducer implements Serializable{ | ||
| 125 | return new EntityManagerProxy(persistenceUnit); | 127 | return new EntityManagerProxy(persistenceUnit); |
| 126 | } | 128 | } |
| 127 | 129 | ||
| 128 | - public EntityManager getEntityManager(String persistenceUnit) { | ||
| 129 | - EntityManager entityManager = null; | ||
| 130 | - | ||
| 131 | - if (cache.containsKey(persistenceUnit)) { | ||
| 132 | - entityManager = cache.get(persistenceUnit); | ||
| 133 | - | ||
| 134 | - } else { | ||
| 135 | - entityManager = factory.create(persistenceUnit).createEntityManager(); | ||
| 136 | - entityManager.setFlushMode(FlushModeType.AUTO); | ||
| 137 | - | ||
| 138 | - cache.put(persistenceUnit, entityManager); | ||
| 139 | - this.logger.info(bundle.getString("entity-manager-was-created", persistenceUnit)); | ||
| 140 | - } | ||
| 141 | - | ||
| 142 | - return entityManager; | ||
| 143 | - } | ||
| 144 | - | ||
| 145 | /** | 130 | /** |
| 146 | * Tries to get persistence unit name from demoiselle.properties. | 131 | * Tries to get persistence unit name from demoiselle.properties. |
| 147 | * | 132 | * |
| @@ -177,23 +162,31 @@ public class EntityManagerProducer implements Serializable{ | @@ -177,23 +162,31 @@ public class EntityManagerProducer implements Serializable{ | ||
| 177 | } | 162 | } |
| 178 | } | 163 | } |
| 179 | 164 | ||
| 180 | - @PostConstruct | ||
| 181 | - protected void init() { | ||
| 182 | - for (String persistenceUnit : factory.getCache().keySet()) { | ||
| 183 | - getEntityManager(persistenceUnit); | ||
| 184 | - } | ||
| 185 | - } | ||
| 186 | - | ||
| 187 | - @PreDestroy | ||
| 188 | - protected void close() { | ||
| 189 | - for (EntityManager entityManager : cache.values()) { | ||
| 190 | - entityManager.close(); | ||
| 191 | - } | ||
| 192 | - | ||
| 193 | - cache.clear(); | 165 | + public EntityManager getEntityManager(String persistenceUnit) { |
| 166 | + return getStore().getEntityManager(persistenceUnit); | ||
| 194 | } | 167 | } |
| 195 | - | 168 | + |
| 196 | public Map<String, EntityManager> getCache() { | 169 | public Map<String, EntityManager> getCache() { |
| 197 | - return cache; | 170 | + return getStore().getCache(); |
| 198 | } | 171 | } |
| 172 | + | ||
| 173 | + private EntityManagerStore getStore(){ | ||
| 174 | + switch(configuration.getEntityManagerScope()){ | ||
| 175 | + case REQUEST: | ||
| 176 | + return storeInstance.select(RequestEntityManagerStore.class).get(); | ||
| 177 | + case APPLICATION: | ||
| 178 | + return storeInstance.select(ApplicationEntityManagerStore.class).get(); | ||
| 179 | + case CONVERSATION: | ||
| 180 | + return storeInstance.select(ConversationEntityManagerStore.class).get(); | ||
| 181 | + case NOSCOPE: | ||
| 182 | + return storeInstance.select(DependentEntityManagerStore.class).get(); | ||
| 183 | + case SESSION: | ||
| 184 | + return storeInstance.select(SessionEntityManagerStore.class).get(); | ||
| 185 | + case VIEW: | ||
| 186 | + return storeInstance.select(ViewEntityManagerStore.class).get(); | ||
| 187 | + default: | ||
| 188 | + return storeInstance.select(RequestEntityManagerStore.class).get(); | ||
| 189 | + } | ||
| 190 | + } | ||
| 191 | + | ||
| 199 | } | 192 | } |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/EntityManagerStore.java
0 → 100644
| @@ -0,0 +1,30 @@ | @@ -0,0 +1,30 @@ | ||
| 1 | +package br.gov.frameworkdemoiselle.internal.producer; | ||
| 2 | + | ||
| 3 | +import java.io.Serializable; | ||
| 4 | +import java.util.Map; | ||
| 5 | + | ||
| 6 | +import javax.annotation.PostConstruct; | ||
| 7 | +import javax.annotation.PreDestroy; | ||
| 8 | +import javax.persistence.EntityManager; | ||
| 9 | + | ||
| 10 | + | ||
| 11 | +public interface EntityManagerStore extends Serializable { | ||
| 12 | + | ||
| 13 | + /** | ||
| 14 | + * Run this to initialize all persistence units. It's recomended this method | ||
| 15 | + * be annotated with {@link PostConstruct}, so it runs as soon as an EntityManager gets injected. | ||
| 16 | + */ | ||
| 17 | + public abstract void initialize(); | ||
| 18 | + | ||
| 19 | + /** | ||
| 20 | + * Run this to close all persistence units. It's recomended this method | ||
| 21 | + * be annotated with {@link PreDestroy}, so it runs as soon as the scope the EntityManager is | ||
| 22 | + * attached to ends. | ||
| 23 | + */ | ||
| 24 | + public abstract void terminate(); | ||
| 25 | + | ||
| 26 | + Map<String, EntityManager> getCache(); | ||
| 27 | + | ||
| 28 | + public EntityManager getEntityManager(String persistenceUnit); | ||
| 29 | + | ||
| 30 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/RequestEntityManagerStore.java
0 → 100644
| @@ -0,0 +1,66 @@ | @@ -0,0 +1,66 @@ | ||
| 1 | +/* | ||
| 2 | + * Demoiselle Framework | ||
| 3 | + * Copyright (C) 2010 SERPRO | ||
| 4 | + * ---------------------------------------------------------------------------- | ||
| 5 | + * This file is part of Demoiselle Framework. | ||
| 6 | + * | ||
| 7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
| 8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
| 9 | + * as published by the Free Software Foundation. | ||
| 10 | + * | ||
| 11 | + * This program is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | + * GNU General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
| 17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
| 18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | + * ---------------------------------------------------------------------------- | ||
| 21 | + * Este arquivo é parte do Framework Demoiselle. | ||
| 22 | + * | ||
| 23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
| 24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
| 25 | + * do Software Livre (FSF). | ||
| 26 | + * | ||
| 27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
| 28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
| 29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
| 30 | + * para maiores detalhes. | ||
| 31 | + * | ||
| 32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
| 33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
| 34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
| 35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
| 36 | + */ | ||
| 37 | +package br.gov.frameworkdemoiselle.internal.producer; | ||
| 38 | + | ||
| 39 | +import javax.annotation.PostConstruct; | ||
| 40 | +import javax.annotation.PreDestroy; | ||
| 41 | +import javax.enterprise.context.RequestScoped; | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * | ||
| 45 | + * Implementation that stores produced entity managers on the request scope. | ||
| 46 | + * | ||
| 47 | + * @author serpro | ||
| 48 | + * | ||
| 49 | + */ | ||
| 50 | +@RequestScoped | ||
| 51 | +public class RequestEntityManagerStore extends AbstractEntityManagerStore { | ||
| 52 | + | ||
| 53 | + private static final long serialVersionUID = 1L; | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + @PostConstruct | ||
| 57 | + public void initialize() { | ||
| 58 | + super.init(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + @Override | ||
| 62 | + @PreDestroy | ||
| 63 | + public void terminate() { | ||
| 64 | + super.close(); | ||
| 65 | + } | ||
| 66 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/SessionEntityManagerStore.java
0 → 100644
| @@ -0,0 +1,67 @@ | @@ -0,0 +1,67 @@ | ||
| 1 | +/* | ||
| 2 | + * Demoiselle Framework | ||
| 3 | + * Copyright (C) 2010 SERPRO | ||
| 4 | + * ---------------------------------------------------------------------------- | ||
| 5 | + * This file is part of Demoiselle Framework. | ||
| 6 | + * | ||
| 7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
| 8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
| 9 | + * as published by the Free Software Foundation. | ||
| 10 | + * | ||
| 11 | + * This program is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | + * GNU General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
| 17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
| 18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | + * ---------------------------------------------------------------------------- | ||
| 21 | + * Este arquivo é parte do Framework Demoiselle. | ||
| 22 | + * | ||
| 23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
| 24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
| 25 | + * do Software Livre (FSF). | ||
| 26 | + * | ||
| 27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
| 28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
| 29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
| 30 | + * para maiores detalhes. | ||
| 31 | + * | ||
| 32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
| 33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
| 34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
| 35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
| 36 | + */ | ||
| 37 | +package br.gov.frameworkdemoiselle.internal.producer; | ||
| 38 | + | ||
| 39 | +import javax.annotation.PostConstruct; | ||
| 40 | +import javax.annotation.PreDestroy; | ||
| 41 | +import javax.enterprise.context.SessionScoped; | ||
| 42 | + | ||
| 43 | +/** | ||
| 44 | + * | ||
| 45 | + * Implementation that stores produced entity managers on the session scope. | ||
| 46 | + * | ||
| 47 | + * @author serpro | ||
| 48 | + * | ||
| 49 | + */ | ||
| 50 | +@SessionScoped | ||
| 51 | +public class SessionEntityManagerStore extends AbstractEntityManagerStore { | ||
| 52 | + | ||
| 53 | + private static final long serialVersionUID = 1L; | ||
| 54 | + | ||
| 55 | + @Override | ||
| 56 | + @PostConstruct | ||
| 57 | + public void initialize() { | ||
| 58 | + super.init(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + @Override | ||
| 62 | + @PreDestroy | ||
| 63 | + public void terminate() { | ||
| 64 | + super.close(); | ||
| 65 | + } | ||
| 66 | + | ||
| 67 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/producer/ViewEntityManagerStore.java
0 → 100644
| @@ -0,0 +1,68 @@ | @@ -0,0 +1,68 @@ | ||
| 1 | +/* | ||
| 2 | + * Demoiselle Framework | ||
| 3 | + * Copyright (C) 2010 SERPRO | ||
| 4 | + * ---------------------------------------------------------------------------- | ||
| 5 | + * This file is part of Demoiselle Framework. | ||
| 6 | + * | ||
| 7 | + * Demoiselle Framework is free software; you can redistribute it and/or | ||
| 8 | + * modify it under the terms of the GNU Lesser General Public License version 3 | ||
| 9 | + * as published by the Free Software Foundation. | ||
| 10 | + * | ||
| 11 | + * This program is distributed in the hope that it will be useful, | ||
| 12 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 13 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 14 | + * GNU General Public License for more details. | ||
| 15 | + * | ||
| 16 | + * You should have received a copy of the GNU Lesser General Public License version 3 | ||
| 17 | + * along with this program; if not, see <http://www.gnu.org/licenses/> | ||
| 18 | + * or write to the Free Software Foundation, Inc., 51 Franklin Street, | ||
| 19 | + * Fifth Floor, Boston, MA 02110-1301, USA. | ||
| 20 | + * ---------------------------------------------------------------------------- | ||
| 21 | + * Este arquivo é parte do Framework Demoiselle. | ||
| 22 | + * | ||
| 23 | + * O Framework Demoiselle é um software livre; você pode redistribuí-lo e/ou | ||
| 24 | + * modificá-lo dentro dos termos da GNU LGPL versão 3 como publicada pela Fundação | ||
| 25 | + * do Software Livre (FSF). | ||
| 26 | + * | ||
| 27 | + * Este programa é distribuído na esperança que possa ser útil, mas SEM NENHUMA | ||
| 28 | + * GARANTIA; sem uma garantia implícita de ADEQUAÇÃO a qualquer MERCADO ou | ||
| 29 | + * APLICAÇÃO EM PARTICULAR. Veja a Licença Pública Geral GNU/LGPL em português | ||
| 30 | + * para maiores detalhes. | ||
| 31 | + * | ||
| 32 | + * Você deve ter recebido uma cópia da GNU LGPL versão 3, sob o título | ||
| 33 | + * "LICENCA.txt", junto com esse programa. Se não, acesse <http://www.gnu.org/licenses/> | ||
| 34 | + * ou escreva para a Fundação do Software Livre (FSF) Inc., | ||
| 35 | + * 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, USA. | ||
| 36 | + */ | ||
| 37 | +package br.gov.frameworkdemoiselle.internal.producer; | ||
| 38 | + | ||
| 39 | +import javax.annotation.PostConstruct; | ||
| 40 | +import javax.annotation.PreDestroy; | ||
| 41 | + | ||
| 42 | +import br.gov.frameworkdemoiselle.annotation.ViewScoped; | ||
| 43 | + | ||
| 44 | +/** | ||
| 45 | + * | ||
| 46 | + * Implementation that stores produced entity managers on the view scope. | ||
| 47 | + * | ||
| 48 | + * @author serpro | ||
| 49 | + * | ||
| 50 | + */ | ||
| 51 | +@ViewScoped | ||
| 52 | +public class ViewEntityManagerStore extends AbstractEntityManagerStore { | ||
| 53 | + | ||
| 54 | + private static final long serialVersionUID = 1L; | ||
| 55 | + | ||
| 56 | + @Override | ||
| 57 | + @PostConstruct | ||
| 58 | + public void initialize() { | ||
| 59 | + super.init(); | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + @Override | ||
| 63 | + @PreDestroy | ||
| 64 | + public void terminate() { | ||
| 65 | + super.close(); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | +} |
impl/extension/jpa/src/main/java/br/gov/frameworkdemoiselle/internal/proxy/EntityManagerProxy.java
| @@ -70,10 +70,18 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -70,10 +70,18 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 70 | 70 | ||
| 71 | private static final long serialVersionUID = 1L; | 71 | private static final long serialVersionUID = 1L; |
| 72 | 72 | ||
| 73 | - /** | 73 | + /* |
| 74 | * Persistence unit of the delegated EntityManager. | 74 | * Persistence unit of the delegated EntityManager. |
| 75 | */ | 75 | */ |
| 76 | private String persistenceUnit; | 76 | private String persistenceUnit; |
| 77 | + | ||
| 78 | + /* | ||
| 79 | + * demoiselle-jpa configuration options | ||
| 80 | + */ | ||
| 81 | + private EntityManagerConfig configuration; | ||
| 82 | + | ||
| 83 | + | ||
| 84 | + private EntityManager delegateCache; | ||
| 77 | 85 | ||
| 78 | /** | 86 | /** |
| 79 | * Constructor based on persistence unit name. | 87 | * Constructor based on persistence unit name. |
| @@ -91,8 +99,15 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -91,8 +99,15 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 91 | * @return Cached EntityManager | 99 | * @return Cached EntityManager |
| 92 | */ | 100 | */ |
| 93 | private EntityManager getEntityManagerDelegate() { | 101 | private EntityManager getEntityManagerDelegate() { |
| 94 | - EntityManagerProducer emp = Beans.getReference(EntityManagerProducer.class); | ||
| 95 | - return emp.getEntityManager(this.persistenceUnit); | 102 | + //Se o produtor de EntityManager não estiver em um escopo, precisamos guardar em cache o EntityManager produzido, |
| 103 | + //do contrário, basta solicitar uma instância do produtor (que estará em um escopo) e obter a instância real | ||
| 104 | + //de EntityManager dele. | ||
| 105 | + if (getConfiguration().getEntityManagerScope()!=EntityManagerScope.NOSCOPE || delegateCache==null){ | ||
| 106 | + EntityManagerProducer emp = Beans.getReference(EntityManagerProducer.class); | ||
| 107 | + delegateCache = emp.getEntityManager(this.persistenceUnit); | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + return delegateCache; | ||
| 96 | } | 111 | } |
| 97 | 112 | ||
| 98 | /* | 113 | /* |
| @@ -113,7 +128,8 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -113,7 +128,8 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 113 | @Override | 128 | @Override |
| 114 | public <T> T merge(T entity) { | 129 | public <T> T merge(T entity) { |
| 115 | joinTransactionIfNecessary(); | 130 | joinTransactionIfNecessary(); |
| 116 | - checkEntityManagerScopePassivable(entity); | 131 | + T managedEntity = getEntityManagerDelegate().merge(entity); |
| 132 | + checkEntityManagerScopePassivable(managedEntity); | ||
| 117 | return getEntityManagerDelegate().merge(entity); | 133 | return getEntityManagerDelegate().merge(entity); |
| 118 | } | 134 | } |
| 119 | 135 | ||
| @@ -155,6 +171,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -155,6 +171,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 155 | @Override | 171 | @Override |
| 156 | public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) { | 172 | public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode) { |
| 157 | joinTransactionIfNecessary(); | 173 | joinTransactionIfNecessary(); |
| 174 | + checkEntityManagerScopePassivable(lockMode); | ||
| 158 | return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode); | 175 | return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode); |
| 159 | } | 176 | } |
| 160 | 177 | ||
| @@ -166,6 +183,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -166,6 +183,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 166 | @Override | 183 | @Override |
| 167 | public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) { | 184 | public <T> T find(Class<T> entityClass, Object primaryKey, LockModeType lockMode, Map<String, Object> properties) { |
| 168 | joinTransactionIfNecessary(); | 185 | joinTransactionIfNecessary(); |
| 186 | + checkEntityManagerScopePassivable(lockMode); | ||
| 169 | return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode, properties); | 187 | return getEntityManagerDelegate().find(entityClass, primaryKey, lockMode, properties); |
| 170 | } | 188 | } |
| 171 | 189 | ||
| @@ -213,6 +231,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -213,6 +231,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 213 | @Override | 231 | @Override |
| 214 | public void lock(Object entity, LockModeType lockMode) { | 232 | public void lock(Object entity, LockModeType lockMode) { |
| 215 | joinTransactionIfNecessary(); | 233 | joinTransactionIfNecessary(); |
| 234 | + checkEntityManagerScopePassivable(lockMode); | ||
| 216 | getEntityManagerDelegate().lock(entity, lockMode); | 235 | getEntityManagerDelegate().lock(entity, lockMode); |
| 217 | } | 236 | } |
| 218 | 237 | ||
| @@ -223,6 +242,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -223,6 +242,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 223 | @Override | 242 | @Override |
| 224 | public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties) { | 243 | public void lock(Object entity, LockModeType lockMode, Map<String, Object> properties) { |
| 225 | joinTransactionIfNecessary(); | 244 | joinTransactionIfNecessary(); |
| 245 | + checkEntityManagerScopePassivable(lockMode); | ||
| 226 | getEntityManagerDelegate().lock(entity, lockMode, properties); | 246 | getEntityManagerDelegate().lock(entity, lockMode, properties); |
| 227 | } | 247 | } |
| 228 | 248 | ||
| @@ -363,7 +383,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -363,7 +383,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 363 | */ | 383 | */ |
| 364 | @Override | 384 | @Override |
| 365 | public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) { | 385 | public <T> TypedQuery<T> createNamedQuery(String name, Class<T> resultClass) { |
| 366 | - return getEntityManagerDelegate().createNamedQuery(name, resultClass); | 386 | + return new TypedQueryProxy<T>(getEntityManagerDelegate().createNamedQuery(name, resultClass),this); |
| 367 | } | 387 | } |
| 368 | 388 | ||
| 369 | /* | 389 | /* |
| @@ -407,7 +427,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -407,7 +427,7 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 407 | */ | 427 | */ |
| 408 | protected final void joinTransactionIfNecessary() { | 428 | protected final void joinTransactionIfNecessary() { |
| 409 | try { | 429 | try { |
| 410 | - getEntityManagerDelegate().getTransaction(); | 430 | + /*EntityTransaction transaction = */getEntityManagerDelegate().getTransaction(); |
| 411 | } catch (IllegalStateException cause) { | 431 | } catch (IllegalStateException cause) { |
| 412 | //IllegalStateException is launched if we are on a JTA entity manager, so | 432 | //IllegalStateException is launched if we are on a JTA entity manager, so |
| 413 | //we assume we need to join transaction instead of creating one. | 433 | //we assume we need to join transaction instead of creating one. |
| @@ -521,29 +541,50 @@ public class EntityManagerProxy implements EntityManager, Serializable { | @@ -521,29 +541,50 @@ public class EntityManagerProxy implements EntityManager, Serializable { | ||
| 521 | return getEntityManagerDelegate().toString(); | 541 | return getEntityManagerDelegate().toString(); |
| 522 | } | 542 | } |
| 523 | 543 | ||
| 524 | - public EntityManagerConfig getConfiguration() { | ||
| 525 | - return Beans.getReference(EntityManagerConfig.class); | ||
| 526 | - } | ||
| 527 | - | ||
| 528 | - public Logger getLogger() { | ||
| 529 | - return Beans.getReference(Logger.class); | ||
| 530 | - } | ||
| 531 | - | ||
| 532 | - public ResourceBundle getBundle(){ | ||
| 533 | - return Beans.getReference(ResourceBundle.class,new NameQualifier("demoiselle-jpa-bundle")); | 544 | + private void checkEntityManagerScopePassivable(Object entity) { |
| 545 | + EntityManagerConfig configuration = getConfiguration(); | ||
| 546 | + if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION | ||
| 547 | + || configuration.getEntityManagerScope()==EntityManagerScope.SESSION | ||
| 548 | + || configuration.getEntityManagerScope()==EntityManagerScope.VIEW){ | ||
| 549 | + | ||
| 550 | + LockModeType lockMode = null; | ||
| 551 | + if (getEntityManagerDelegate().contains(entity)){ | ||
| 552 | + lockMode = getEntityManagerDelegate().getLockMode(entity); | ||
| 553 | + } | ||
| 554 | + checkEntityManagerScopePassivable(lockMode); | ||
| 555 | + } | ||
| 534 | } | 556 | } |
| 535 | 557 | ||
| 536 | - private void checkEntityManagerScopePassivable(Object entity) { | 558 | + private void checkEntityManagerScopePassivable(LockModeType lockMode) { |
| 537 | EntityManagerConfig configuration = getConfiguration(); | 559 | EntityManagerConfig configuration = getConfiguration(); |
| 538 | if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION | 560 | if (configuration.getEntityManagerScope()==EntityManagerScope.CONVERSATION |
| 539 | || configuration.getEntityManagerScope()==EntityManagerScope.SESSION | 561 | || configuration.getEntityManagerScope()==EntityManagerScope.SESSION |
| 540 | || configuration.getEntityManagerScope()==EntityManagerScope.VIEW){ | 562 | || configuration.getEntityManagerScope()==EntityManagerScope.VIEW){ |
| 541 | - LockModeType lockMode = getEntityManagerDelegate().getLockMode(entity); | ||
| 542 | - if (lockMode != LockModeType.OPTIMISTIC_FORCE_INCREMENT && lockMode != LockModeType.WRITE){ | ||
| 543 | - String message = getBundle().getString("passivable-scope-with-pessimistic-lock" , configuration.getEntityManagerScope().toString()); | 563 | + |
| 564 | + if (lockMode!=null | ||
| 565 | + && lockMode!=LockModeType.NONE | ||
| 566 | + && lockMode!=LockModeType.OPTIMISTIC_FORCE_INCREMENT){ | ||
| 567 | + String message = getBundle().getString("passivable-scope-without-optimistic-lock" , configuration.getEntityManagerScope().toString()); | ||
| 544 | getLogger().error(message); | 568 | getLogger().error(message); |
| 545 | throw new DemoiselleException(message); | 569 | throw new DemoiselleException(message); |
| 546 | } | 570 | } |
| 547 | } | 571 | } |
| 548 | } | 572 | } |
| 573 | + | ||
| 574 | + private EntityManagerConfig getConfiguration(){ | ||
| 575 | + if (configuration==null){ | ||
| 576 | + configuration = Beans.getReference(EntityManagerConfig.class); | ||
| 577 | + } | ||
| 578 | + | ||
| 579 | + return configuration; | ||
| 580 | + } | ||
| 581 | + | ||
| 582 | + private Logger getLogger() { | ||
| 583 | + return Beans.getReference(Logger.class); | ||
| 584 | + } | ||
| 585 | + | ||
| 586 | + private ResourceBundle getBundle(){ | ||
| 587 | + return Beans.getReference(ResourceBundle.class,new NameQualifier("demoiselle-jpa-bundle")); | ||
| 588 | + } | ||
| 589 | + | ||
| 549 | } | 590 | } |
impl/extension/jpa/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
impl/extension/jpa/src/main/resources/demoiselle-jpa-bundle.properties
| @@ -46,5 +46,5 @@ no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a c | @@ -46,5 +46,5 @@ no-transaction-active=Nenhuma transa\u00E7\u00E3o est\u00E1 ativa, verifique a c | ||
| 46 | malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados. | 46 | malformed-jpql=Consulta JPQL mal formada para pagina\u00E7\u00E3o de dados. |
| 47 | 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 | 47 | 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 |
| 48 | entity-manager-scope-not-defined=N\u00E3o foi poss\u00EDvel ler o escopo configurado para o Entity Manager, usando o escopo padr\u00E3o [{0}] | 48 | entity-manager-scope-not-defined=N\u00E3o foi poss\u00EDvel ler o escopo configurado para o Entity Manager, usando o escopo padr\u00E3o [{0}] |
| 49 | -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]) | 49 | +passivable-scope-without-optimistic-lock=Um Entity Manager armazenado no escopo [{0}] suporta apenas trava otimista com vers\u00E3o. Use o tipo adequado ou remova a trava. (veja [LockModeType.OPTIMISTIC_FORCE_INCREMENT]) |
| 50 | defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager | 50 | defining-entity-manager-scope=Definindo escopo [{0}] para produtor de Entity Manager |
| 51 | \ No newline at end of file | 51 | \ No newline at end of file |
impl/extension/jpa/src/test/java/producer/NoScopedProducerTest.java
0 → 100644
| @@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
| 1 | +package producer; | ||
| 2 | + | ||
| 3 | +import static org.junit.Assert.assertEquals; | ||
| 4 | +import static org.junit.Assert.assertNotNull; | ||
| 5 | +import static org.junit.Assert.assertTrue; | ||
| 6 | + | ||
| 7 | +import javax.persistence.EntityManager; | ||
| 8 | + | ||
| 9 | +import org.jboss.arquillian.container.test.api.Deployment; | ||
| 10 | +import org.jboss.arquillian.junit.Arquillian; | ||
| 11 | +import org.jboss.shrinkwrap.api.spec.WebArchive; | ||
| 12 | +import org.junit.Test; | ||
| 13 | +import org.junit.runner.RunWith; | ||
| 14 | + | ||
| 15 | +import test.Tests; | ||
| 16 | +import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy; | ||
| 17 | +import br.gov.frameworkdemoiselle.util.Beans; | ||
| 18 | +import br.gov.frameworkdemoiselle.util.NameQualifier; | ||
| 19 | + | ||
| 20 | +@RunWith(Arquillian.class) | ||
| 21 | +public class NoScopedProducerTest { | ||
| 22 | + | ||
| 23 | + private static final String PATH = "src/test/resources/producer"; | ||
| 24 | + | ||
| 25 | + @Deployment | ||
| 26 | + public static WebArchive createDeployment() { | ||
| 27 | + WebArchive deployment = Tests.createDeployment(NoScopedProducerTest.class); | ||
| 28 | + deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml"); | ||
| 29 | + deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle_noscoped.properties"), "demoiselle.properties"); | ||
| 30 | + | ||
| 31 | + return deployment; | ||
| 32 | + } | ||
| 33 | + | ||
| 34 | + @Test | ||
| 35 | + public void produceOneEntityManagerPerInjection() { | ||
| 36 | + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 37 | + | ||
| 38 | + assertNotNull(m1); | ||
| 39 | + assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 40 | + | ||
| 41 | + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 42 | + | ||
| 43 | + assertNotNull(m2); | ||
| 44 | + assertEquals(EntityManagerProxy.class, m2.getClass()); | ||
| 45 | + | ||
| 46 | + MyEntity entity = new MyEntity(); | ||
| 47 | + entity.setId(createId("testID")); | ||
| 48 | + | ||
| 49 | + m1.persist(entity); | ||
| 50 | + | ||
| 51 | + assertTrue( ! m2.contains(entity)); | ||
| 52 | + assertTrue(m1.contains(entity)); | ||
| 53 | + } | ||
| 54 | + | ||
| 55 | + private String createId(String id) { | ||
| 56 | + return this.getClass().getName() + "_" + id; | ||
| 57 | + } | ||
| 58 | + | ||
| 59 | +} |
impl/extension/jpa/src/test/java/producer/ProducerTest.java
| @@ -1,110 +0,0 @@ | @@ -1,110 +0,0 @@ | ||
| 1 | -package producer; | ||
| 2 | - | ||
| 3 | -import static org.junit.Assert.assertEquals; | ||
| 4 | -import static org.junit.Assert.assertNotNull; | ||
| 5 | -import static org.junit.Assert.assertTrue; | ||
| 6 | - | ||
| 7 | -import javax.persistence.EntityManager; | ||
| 8 | - | ||
| 9 | -import org.jboss.arquillian.container.test.api.Deployment; | ||
| 10 | -import org.jboss.arquillian.junit.Arquillian; | ||
| 11 | -import org.jboss.shrinkwrap.api.spec.WebArchive; | ||
| 12 | -import org.junit.Test; | ||
| 13 | -import org.junit.runner.RunWith; | ||
| 14 | - | ||
| 15 | -import test.Tests; | ||
| 16 | -import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy; | ||
| 17 | -import br.gov.frameworkdemoiselle.util.Beans; | ||
| 18 | -import br.gov.frameworkdemoiselle.util.NameQualifier; | ||
| 19 | - | ||
| 20 | -@RunWith(Arquillian.class) | ||
| 21 | -public class ProducerTest { | ||
| 22 | - | ||
| 23 | - private static final String PATH = "src/test/resources/producer"; | ||
| 24 | - | ||
| 25 | - @Deployment//(name="request_scoped_producer") | ||
| 26 | - public static WebArchive createDeployment() { | ||
| 27 | - WebArchive deployment = Tests.createDeployment(ProducerTest.class); | ||
| 28 | - deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml"); | ||
| 29 | - deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle.properties"), "demoiselle.properties"); | ||
| 30 | - | ||
| 31 | - return deployment; | ||
| 32 | - } | ||
| 33 | - | ||
| 34 | - /*@Deployment(name="no_scoped_producer") | ||
| 35 | - public static WebArchive createNoScopedDeployment() { | ||
| 36 | - WebArchive deployment = Tests.createDeployment(ProducerTest.class); | ||
| 37 | - deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml"); | ||
| 38 | - deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle_noscoped.properties"), "demoiselle.properties"); | ||
| 39 | - | ||
| 40 | - return deployment; | ||
| 41 | - }*/ | ||
| 42 | - | ||
| 43 | - @Test | ||
| 44 | - public void produceEntityManager() { | ||
| 45 | - EntityManager manager = Beans.getReference(EntityManager.class); | ||
| 46 | - | ||
| 47 | - assertNotNull(manager); | ||
| 48 | - assertEquals(EntityManagerProxy.class, manager.getClass()); | ||
| 49 | - } | ||
| 50 | - | ||
| 51 | - @Test | ||
| 52 | - public void produceMultipleEntityManagers() { | ||
| 53 | - EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 54 | - | ||
| 55 | - assertNotNull(m1); | ||
| 56 | - assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 57 | - | ||
| 58 | - EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu2")); | ||
| 59 | - | ||
| 60 | - assertNotNull(m2); | ||
| 61 | - assertEquals(EntityManagerProxy.class, m2.getClass()); | ||
| 62 | - } | ||
| 63 | - | ||
| 64 | - @Test | ||
| 65 | - public void produceOneEntityManagerPerRequest() { | ||
| 66 | - EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 67 | - | ||
| 68 | - assertNotNull(m1); | ||
| 69 | - assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 70 | - | ||
| 71 | - EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 72 | - | ||
| 73 | - assertNotNull(m2); | ||
| 74 | - assertEquals(EntityManagerProxy.class, m2.getClass()); | ||
| 75 | - | ||
| 76 | - MyEntity entity = new MyEntity(); | ||
| 77 | - entity.setId(createId("testID")); | ||
| 78 | - | ||
| 79 | - m1.persist(entity); | ||
| 80 | - | ||
| 81 | - assertTrue(m2.contains(entity)); | ||
| 82 | - } | ||
| 83 | - | ||
| 84 | - /*@Test | ||
| 85 | - public void produceOneEntityManagerPerInjection() { | ||
| 86 | - //Testa se ao usar o produtor sem escopo, mais de um entity manager é criado a cada injeção. | ||
| 87 | - | ||
| 88 | - EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 89 | - | ||
| 90 | - assertNotNull(m1); | ||
| 91 | - assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 92 | - | ||
| 93 | - EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 94 | - | ||
| 95 | - assertNotNull(m2); | ||
| 96 | - assertEquals(EntityManagerProxy.class, m2.getClass()); | ||
| 97 | - | ||
| 98 | - MyEntity entity = new MyEntity(); | ||
| 99 | - entity.setId(createId("testID")); | ||
| 100 | - | ||
| 101 | - m1.persist(entity); | ||
| 102 | - | ||
| 103 | - assertTrue( ! m2.contains(entity)); | ||
| 104 | - }*/ | ||
| 105 | - | ||
| 106 | - private String createId(String id) { | ||
| 107 | - return this.getClass().getName() + "_" + id; | ||
| 108 | - } | ||
| 109 | - | ||
| 110 | -} |
impl/extension/jpa/src/test/java/producer/RequestScopedProducerTest.java
0 → 100644
| @@ -0,0 +1,118 @@ | @@ -0,0 +1,118 @@ | ||
| 1 | +package producer; | ||
| 2 | + | ||
| 3 | +import static org.junit.Assert.assertEquals; | ||
| 4 | +import static org.junit.Assert.assertNotNull; | ||
| 5 | +import static org.junit.Assert.assertTrue; | ||
| 6 | + | ||
| 7 | +import javax.persistence.EntityManager; | ||
| 8 | + | ||
| 9 | +import org.jboss.arquillian.container.test.api.Deployment; | ||
| 10 | +import org.jboss.arquillian.junit.Arquillian; | ||
| 11 | +import org.jboss.shrinkwrap.api.spec.WebArchive; | ||
| 12 | +import org.jboss.weld.context.http.HttpRequestContext; | ||
| 13 | +import org.junit.Test; | ||
| 14 | +import org.junit.runner.RunWith; | ||
| 15 | + | ||
| 16 | +import test.Tests; | ||
| 17 | +import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy; | ||
| 18 | +import br.gov.frameworkdemoiselle.util.Beans; | ||
| 19 | +import br.gov.frameworkdemoiselle.util.NameQualifier; | ||
| 20 | + | ||
| 21 | +@RunWith(Arquillian.class) | ||
| 22 | +public class RequestScopedProducerTest { | ||
| 23 | + | ||
| 24 | + private static final String PATH = "src/test/resources/producer"; | ||
| 25 | + | ||
| 26 | + @Deployment | ||
| 27 | + public static WebArchive createDeployment() { | ||
| 28 | + WebArchive deployment = Tests.createDeployment(RequestScopedProducerTest.class); | ||
| 29 | + deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml"); | ||
| 30 | + deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle.properties"), "demoiselle.properties"); | ||
| 31 | + | ||
| 32 | + return deployment; | ||
| 33 | + } | ||
| 34 | + | ||
| 35 | + @Test | ||
| 36 | + public void produceEntityManager() { | ||
| 37 | + EntityManager manager = Beans.getReference(EntityManager.class); | ||
| 38 | + | ||
| 39 | + assertNotNull(manager); | ||
| 40 | + assertEquals(EntityManagerProxy.class, manager.getClass()); | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + @Test | ||
| 44 | + public void produceMultipleEntityManagers() { | ||
| 45 | + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 46 | + | ||
| 47 | + assertNotNull(m1); | ||
| 48 | + assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 49 | + | ||
| 50 | + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu2")); | ||
| 51 | + | ||
| 52 | + assertNotNull(m2); | ||
| 53 | + assertEquals(EntityManagerProxy.class, m2.getClass()); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + @Test | ||
| 57 | + public void produceOneEntityManagerPerRequest() { | ||
| 58 | + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 59 | + | ||
| 60 | + assertNotNull(m1); | ||
| 61 | + assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 62 | + | ||
| 63 | + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 64 | + | ||
| 65 | + assertNotNull(m2); | ||
| 66 | + assertEquals(EntityManagerProxy.class, m2.getClass()); | ||
| 67 | + | ||
| 68 | + MyEntity entity = new MyEntity(); | ||
| 69 | + entity.setId(createId("testID")); | ||
| 70 | + | ||
| 71 | + m1.persist(entity); | ||
| 72 | + | ||
| 73 | + assertTrue(m2.contains(entity)); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + @Test | ||
| 77 | + public void produceDifferentEntityManagerPerRequest() { | ||
| 78 | + HttpRequestContext weldContext = Beans.getReference(HttpRequestContext.class); | ||
| 79 | + | ||
| 80 | + boolean wasNotActive = false; | ||
| 81 | + if (!weldContext.isActive()){ | ||
| 82 | + wasNotActive = true; | ||
| 83 | + weldContext.activate(); | ||
| 84 | + } | ||
| 85 | + | ||
| 86 | + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 87 | + assertNotNull(m1); | ||
| 88 | + assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 89 | + | ||
| 90 | + MyEntity entity = new MyEntity(); | ||
| 91 | + entity.setId(createId("testID")); | ||
| 92 | + | ||
| 93 | + m1.persist(entity); | ||
| 94 | + assertTrue(m1.contains(entity)); | ||
| 95 | + | ||
| 96 | + weldContext.invalidate(); | ||
| 97 | + weldContext.deactivate(); | ||
| 98 | + | ||
| 99 | + if (!weldContext.isActive()){ | ||
| 100 | + weldContext.activate(); | ||
| 101 | + } | ||
| 102 | + | ||
| 103 | + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 104 | + | ||
| 105 | + assertTrue( m2.isOpen() ); | ||
| 106 | + assertTrue( !m2.contains(entity)); | ||
| 107 | + | ||
| 108 | + if (wasNotActive && weldContext.isActive()){ | ||
| 109 | + weldContext.invalidate(); | ||
| 110 | + weldContext.deactivate(); | ||
| 111 | + } | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + private String createId(String id) { | ||
| 115 | + return this.getClass().getName() + "_" + id; | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | +} |
impl/extension/jpa/src/test/java/producer/ViewScopedProducerTest.java
0 → 100644
| @@ -0,0 +1,83 @@ | @@ -0,0 +1,83 @@ | ||
| 1 | +package producer; | ||
| 2 | + | ||
| 3 | +import static org.junit.Assert.assertEquals; | ||
| 4 | +import static org.junit.Assert.assertNotNull; | ||
| 5 | +import static org.junit.Assert.assertTrue; | ||
| 6 | + | ||
| 7 | +import javax.enterprise.context.ContextNotActiveException; | ||
| 8 | +import javax.persistence.EntityManager; | ||
| 9 | + | ||
| 10 | +import org.jboss.arquillian.container.test.api.Deployment; | ||
| 11 | +import org.jboss.arquillian.junit.Arquillian; | ||
| 12 | +import org.jboss.shrinkwrap.api.spec.WebArchive; | ||
| 13 | +import org.junit.Test; | ||
| 14 | +import org.junit.runner.RunWith; | ||
| 15 | + | ||
| 16 | +import test.Tests; | ||
| 17 | +import br.gov.frameworkdemoiselle.context.ViewContext; | ||
| 18 | +import br.gov.frameworkdemoiselle.internal.proxy.EntityManagerProxy; | ||
| 19 | +import br.gov.frameworkdemoiselle.util.Beans; | ||
| 20 | +import br.gov.frameworkdemoiselle.util.NameQualifier; | ||
| 21 | + | ||
| 22 | +@RunWith(Arquillian.class) | ||
| 23 | +public class ViewScopedProducerTest { | ||
| 24 | + | ||
| 25 | + private static final String PATH = "src/test/resources/producer"; | ||
| 26 | + | ||
| 27 | + @Deployment | ||
| 28 | + public static WebArchive createDeployment() { | ||
| 29 | + WebArchive deployment = Tests.createDeployment(ViewScopedProducerTest.class); | ||
| 30 | + deployment.addAsResource(Tests.createFileAsset(PATH + "/persistence.xml"), "META-INF/persistence.xml"); | ||
| 31 | + deployment.addAsResource(Tests.createFileAsset(PATH + "/demoiselle_viewscoped.properties"), "demoiselle.properties"); | ||
| 32 | + | ||
| 33 | + return deployment; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + @Test | ||
| 37 | + public void produceOneEntityManagerPerView() { | ||
| 38 | + ViewContext ctx = Beans.getReference(ViewContext.class); | ||
| 39 | + ctx.activate(); | ||
| 40 | + | ||
| 41 | + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 42 | + | ||
| 43 | + assertNotNull(m1); | ||
| 44 | + assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 45 | + | ||
| 46 | + EntityManager m2 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 47 | + | ||
| 48 | + assertNotNull(m2); | ||
| 49 | + assertEquals(EntityManagerProxy.class, m2.getClass()); | ||
| 50 | + | ||
| 51 | + MyEntity entity = new MyEntity(); | ||
| 52 | + entity.setId(createId("testID")); | ||
| 53 | + | ||
| 54 | + m1.persist(entity); | ||
| 55 | + | ||
| 56 | + assertTrue(m2.contains(entity)); | ||
| 57 | + | ||
| 58 | + ctx.deactivate(); | ||
| 59 | + } | ||
| 60 | + | ||
| 61 | + @Test(expected=ContextNotActiveException.class) | ||
| 62 | + public void errorWhenContextNotActive() { | ||
| 63 | + ViewContext ctx = Beans.getReference(ViewContext.class); | ||
| 64 | + if (ctx.isActive()){ | ||
| 65 | + ctx.deactivate(); | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + EntityManager m1 = Beans.getReference(EntityManager.class, new NameQualifier("pu")); | ||
| 69 | + | ||
| 70 | + assertNotNull(m1); | ||
| 71 | + assertEquals(EntityManagerProxy.class, m1.getClass()); | ||
| 72 | + | ||
| 73 | + MyEntity entity = new MyEntity(); | ||
| 74 | + entity.setId(createId("testID")); | ||
| 75 | + | ||
| 76 | + m1.persist(entity); | ||
| 77 | + } | ||
| 78 | + | ||
| 79 | + private String createId(String id) { | ||
| 80 | + return this.getClass().getName() + "_" + id; | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | +} |
impl/extension/jpa/src/test/java/transaction/interceptor/JPATransactionTest.java
| @@ -66,7 +66,6 @@ public class JPATransactionTest { | @@ -66,7 +66,6 @@ public class JPATransactionTest { | ||
| 66 | 66 | ||
| 67 | @Test | 67 | @Test |
| 68 | public void commitWithSuccess() { | 68 | public void commitWithSuccess() { |
| 69 | - | ||
| 70 | tb.commitWithSuccess(); | 69 | tb.commitWithSuccess(); |
| 71 | 70 | ||
| 72 | MyEntity1 entity1 = em1.find(MyEntity1.class, tb.createId("id-1")); | 71 | MyEntity1 entity1 = em1.find(MyEntity1.class, tb.createId("id-1")); |
| @@ -78,7 +77,6 @@ public class JPATransactionTest { | @@ -78,7 +77,6 @@ public class JPATransactionTest { | ||
| 78 | 77 | ||
| 79 | @Test | 78 | @Test |
| 80 | public void rollbackWithSuccess() { | 79 | public void rollbackWithSuccess() { |
| 81 | - | ||
| 82 | try { | 80 | try { |
| 83 | tb.rollbackWithSuccess(); | 81 | tb.rollbackWithSuccess(); |
| 84 | } catch (Exception e) { | 82 | } catch (Exception e) { |
impl/extension/jpa/src/test/resources/producer/demoiselle_viewscoped.properties
0 → 100644