[seam-commits] Seam SVN: r13669 - in modules/persistence/trunk/impl/src: main/java/org/jboss/seam/persistence/transaction and 3 other directories.
seam-commits at lists.jboss.org
seam-commits at lists.jboss.org
Mon Aug 30 19:56:11 EDT 2010
Author: swd847
Date: 2010-08-30 19:56:10 -0400 (Mon, 30 Aug 2010)
New Revision: 13669
Added:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/DefaultPersistenceProvider.java
modules/persistence/trunk/impl/src/main/resources/META-INF/services/org.jboss.seam.persistence.SeamPersistenceProvider
Modified:
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/HibernatePersistenceProvider.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextBeanLifecycle.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextExtension.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextProxyHandler.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/PersistenceContextProxyHandler.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/PersistenceContextsImpl.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/SeamPersistenceProvider.java
modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/EntityTransaction.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/test/HibernateSearchTest.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/test/ManagedPersistenceContextFlushModeTest.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionScopedTest.java
modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/UserTransactionTest.java
Log:
change persistence providers to use a ServiceLoader approach
Copied: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/DefaultPersistenceProvider.java (from rev 13665, modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/SeamPersistenceProvider.java)
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/DefaultPersistenceProvider.java (rev 0)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/DefaultPersistenceProvider.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -0,0 +1,219 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, Red Hat, Inc., and individual contributors
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.seam.persistence;
+
+import java.lang.reflect.Method;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.persistence.EntityManager;
+import javax.persistence.OptimisticLockException;
+import javax.transaction.Synchronization;
+
+import org.jboss.seam.persistence.transaction.FlushModeType;
+import org.jboss.weld.extensions.defaultbean.DefaultBean;
+
+/**
+ * Abstraction layer for persistence providers (JPA implementations). This class
+ * provides a working base implementation that can be optimized for performance
+ * and non-standardized features by extending and overriding the methods.
+ *
+ * The methods on this class are a great todo list for the next rev of the JPA
+ * spec ;-)
+ *
+ * @author Gavin King
+ * @author Pete Muir
+ * @author Stuart Douglas
+ *
+ */
+ at DefaultBean(type = DefaultPersistenceProvider.class)
+public class DefaultPersistenceProvider implements SeamPersistenceProvider
+{
+ public enum Feature
+ {
+ /**
+ * Identifies whether this JPA provider supports using a wildcard as the
+ * subject of a count query.
+ *
+ * <p>
+ * Here's a count query that uses a wildcard as the subject.
+ * </p>
+ *
+ * <pre>
+ * select count(*) from Vehicle v
+ * </pre>
+ * <p>
+ * Per the JPA 1.0 spec, using a wildcard as a subject of a count query is
+ * not permitted. Instead, the subject must be the entity or the alias, as
+ * in this count query:
+ * </p>
+ *
+ * <pre>
+ * select count(v) from Vehicle v
+ * </pre>
+ * <p>
+ * Hibernate supports the wildcard syntax as an vendor extension.
+ * Furthermore, Hibernate produces an invalid SQL query when using the
+ * compliant subject if the entity has a composite primary key. Therefore,
+ * we prefer to use the wildcard syntax if it is supported.
+ * </p>
+ */
+ WILDCARD_AS_COUNT_QUERY_SUBJECT
+ }
+
+ protected Set<Feature> featureSet = new HashSet<Feature>();
+
+ /**
+ * Indicate whether this JPA provider supports the feature defined by the
+ * provided Feature enum value.
+ */
+ public boolean supportsFeature(Feature feature)
+ {
+ return featureSet.contains(feature);
+ }
+
+ public boolean isCorrectProvider(EntityManager em)
+ {
+ return true;
+ }
+
+ public void setFlushMode(EntityManager entityManager, FlushModeType type)
+ {
+ switch (type)
+ {
+ case AUTO:
+ entityManager.setFlushMode(javax.persistence.FlushModeType.AUTO);
+ break;
+ case COMMIT:
+ entityManager.setFlushMode(javax.persistence.FlushModeType.COMMIT);
+ break;
+ case MANUAL:
+ setFlushModeManual(entityManager);
+ break;
+ default:
+ throw new RuntimeException("Unkown flush mode: " + type);
+ }
+ }
+
+ public void setFlushModeManual(EntityManager entityManager)
+ {
+ throw new UnsupportedOperationException("Use of FlushMode.MANUAL requires Hibernate as the persistence provider. Please use Hibernate, a custom persistenceProvider, or remove the MANUAL flush mode setting.");
+ }
+
+ public FlushModeType getRenderFlushMode()
+ {
+ return FlushModeType.COMMIT;
+ }
+
+ public boolean isDirty(EntityManager entityManager)
+ {
+ return true; // best we can do!
+ }
+
+ public Object getId(Object bean, EntityManager entityManager)
+ {
+ // return Entity.forBean(bean).getIdentifier(bean);
+ return null;
+ }
+
+ public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
+ {
+ return null;
+ // return Entity.forBean(bean).getName();
+ }
+
+ public Object getVersion(Object bean, EntityManager entityManager)
+ {
+ return null;
+ // return Entity.forBean(bean).getVersion(bean);
+ }
+
+ public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
+ {
+ boolean equal;
+ if (oldVersion instanceof Date)
+ {
+ equal = ((Date) oldVersion).getTime() == ((Date) version).getTime();
+ }
+ else
+ {
+ equal = oldVersion.equals(version);
+ }
+ if (!equal)
+ {
+ throw new OptimisticLockException("Current database version number does not match passivated version number");
+ }
+ }
+
+ public boolean registerSynchronization(Synchronization sync, EntityManager entityManager)
+ {
+ return false; // best we can do!
+ }
+
+ public Object proxyDelegate(Object delegate)
+ {
+ return delegate;
+ }
+
+ public EntityManager proxyEntityManager(EntityManager entityManager)
+ {
+ return entityManager;
+ }
+
+ public Set<Class<?>> getAdditionalEntityManagerInterfaces()
+ {
+ return Collections.emptySet();
+ }
+
+ public Class<?> getBeanClass(Object bean)
+ {
+ return null;
+ // return Entity.forBean(bean).getBeanClass();
+ }
+
+ public Method getPostLoadMethod(Object bean, EntityManager entityManager)
+ {
+ return null;
+ // return Entity.forBean(bean).getPostLoadMethod();
+ }
+
+ public Method getPrePersistMethod(Object bean, EntityManager entityManager)
+ {
+ return null;
+ // return Entity.forBean(bean).getPrePersistMethod();
+ }
+
+ public Method getPreUpdateMethod(Object bean, EntityManager entityManager)
+ {
+ return null;
+ // return Entity.forBean(bean).getPreUpdateMethod();
+ }
+
+ public Method getPreRemoveMethod(Object bean, EntityManager entityManager)
+ {
+ return null;
+ // return Entity.forBean(bean).getPreRemoveMethod();
+ }
+
+}
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/HibernatePersistenceProvider.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/HibernatePersistenceProvider.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/HibernatePersistenceProvider.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -4,7 +4,6 @@
import java.util.Collections;
import java.util.Set;
-import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Synchronization;
@@ -27,12 +26,9 @@
* @author Stuart Douglas
*
*/
-public class HibernatePersistenceProvider extends SeamPersistenceProvider
+public class HibernatePersistenceProvider extends DefaultPersistenceProvider
{
- @Inject
- Instance<PersistenceContextsImpl> persistenceContexts;
-
private static Logger log = LoggerFactory.getLogger(HibernatePersistenceProvider.class);
private static Method FULL_TEXT_SESSION_CONSTRUCTOR;
private static Method FULL_TEXT_ENTITYMANAGER_CONSTRUCTOR;
@@ -91,6 +87,12 @@
}
@Override
+ public boolean isCorrectProvider(EntityManager em)
+ {
+ return em.getDelegate() instanceof Session;
+ }
+
+ @Override
public void setFlushModeManual(EntityManager entityManager)
{
try
@@ -104,9 +106,9 @@
}
@Override
- public void setRenderFlushMode()
+ public FlushModeType getRenderFlushMode()
{
- persistenceContexts.get().changeFlushMode(FlushModeType.MANUAL, true);
+ return FlushModeType.MANUAL;
}
@Override
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContext.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -41,4 +41,6 @@
public Class<?> getBeanType();
+ public SeamPersistenceProvider getProvider();
+
}
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextBeanLifecycle.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextBeanLifecycle.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextBeanLifecycle.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -26,6 +26,8 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Set;
import javax.enterprise.context.ContextNotActiveException;
@@ -54,19 +56,22 @@
private final Constructor<?> proxyConstructor;
+ private SeamPersistenceProvider persistenceProvider;
+
private PersistenceContexts persistenceContexts;
- private SeamPersistenceProvider persistenceProvider;
-
protected final Annotation[] qualifiers;
protected final BeanManager manager;
private EntityManagerFactory emf;
- public ManagedPersistenceContextBeanLifecycle(Set<Annotation> qualifiers, ClassLoader loader, BeanManager manager, Set<Class<?>> additionalinterfaces)
+ private final List<SeamPersistenceProvider> persistenceProviders;
+
+ public ManagedPersistenceContextBeanLifecycle(Set<Annotation> qualifiers, ClassLoader loader, BeanManager manager, Set<Class<?>> additionalinterfaces, List<SeamPersistenceProvider> persistenceProviders)
{
this.manager = manager;
+ this.persistenceProviders = new ArrayList<SeamPersistenceProvider>(persistenceProviders);
Class<?>[] interfaces = new Class[additionalinterfaces.size() + 3];
int count = 0;
for (Class<?> i : additionalinterfaces)
@@ -92,6 +97,7 @@
{
this.qualifiers[i++] = a;
}
+
}
/**
@@ -103,10 +109,10 @@
{
EntityManagerFactory emf = getEntityManagerFactory();
EntityManager entityManager = emf.createEntityManager();
- entityManager = getPersistenceProvider().proxyEntityManager(entityManager);
- ManagedPersistenceContextProxyHandler handler = new ManagedPersistenceContextProxyHandler(entityManager, manager, bean.getQualifiers(), getPersistenceContexts());
+ entityManager = getPersistenceProvider(entityManager).proxyEntityManager(entityManager);
+ ManagedPersistenceContextProxyHandler handler = new ManagedPersistenceContextProxyHandler(entityManager, manager, bean.getQualifiers(), getPersistenceContexts(), getPersistenceProvider(entityManager));
EntityManager proxy = (EntityManager) proxyConstructor.newInstance(handler);
- getPersistenceProvider().setFlushMode(proxy, getPersistenceContexts().getFlushMode());
+ getPersistenceProvider(entityManager).setFlushMode(proxy, getPersistenceContexts().getFlushMode());
return proxy;
}
catch (Exception e)
@@ -144,17 +150,18 @@
return persistenceContexts;
}
- private SeamPersistenceProvider getPersistenceProvider()
+ private SeamPersistenceProvider getPersistenceProvider(EntityManager em)
{
if (persistenceProvider == null)
{
- Bean<SeamPersistenceProvider> bean = (Bean) manager.resolve(manager.getBeans(SeamPersistenceProvider.class, DefaultLiteral.INSTANCE));
- if (bean == null)
+ for (SeamPersistenceProvider i : persistenceProviders)
{
- throw new RuntimeException("Could not find SeamPersistenceProvider bean");
+ if (i.isCorrectProvider(em))
+ {
+ persistenceProvider = i;
+ break;
+ }
}
- CreationalContext<SeamPersistenceProvider> ctx = manager.createCreationalContext(bean);
- persistenceProvider = (SeamPersistenceProvider) manager.getReference(bean, SeamPersistenceProvider.class, ctx);
}
return persistenceProvider;
}
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextExtension.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextExtension.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextExtension.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -22,7 +22,9 @@
package org.jboss.seam.persistence;
import java.lang.annotation.Annotation;
+import java.util.ArrayList;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
import javax.enterprise.context.Dependent;
@@ -33,6 +35,7 @@
import javax.enterprise.inject.spi.AnnotatedMethod;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.ProcessAnnotatedType;
import javax.persistence.EntityManager;
@@ -44,6 +47,7 @@
import org.jboss.weld.extensions.literal.AnyLiteral;
import org.jboss.weld.extensions.literal.ApplicationScopedLiteral;
import org.jboss.weld.extensions.literal.DefaultLiteral;
+import org.jboss.weld.extensions.util.service.ServiceLoader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -60,8 +64,21 @@
Set<Bean<?>> beans = new HashSet<Bean<?>>();
+ List<SeamPersistenceProvider> persistenceProviders = new ArrayList<SeamPersistenceProvider>();
+
private static final Logger log = LoggerFactory.getLogger(ManagedPersistenceContextExtension.class);
+ public void beforeBeanDiscovery(@Observes BeforeBeanDiscovery event)
+ {
+ ServiceLoader<SeamPersistenceProvider> providers = ServiceLoader.load(SeamPersistenceProvider.class);
+ for (SeamPersistenceProvider i : providers)
+ {
+ persistenceProviders.add(i);
+ }
+ // this is always the last one considered
+ persistenceProviders.add(new DefaultPersistenceProvider());
+ }
+
/**
* loops through the fields on an AnnotatedType looking for a @PersistnceUnit
* producer field that is annotated {@link SeamManaged}. Then a corresponding
@@ -113,13 +130,12 @@
// This allows the user to manually configure an EntityManagerFactory
// and return it from a producer method
}
- // not look for SMPC's that are configured programatically via a producer
- // method the producer method has its scope changes to application scoped
- // this allows for programati config of the SMPC
+ // now look for SMPC's that are configured programatically via a producer
+ // method. This looks for both EMF's and SessionFactories
+ // The producer method has its scope changes to application scoped
+ // this allows for programatic config of the SMPC
for (AnnotatedMethod<? super T> m : event.getAnnotatedType().getMethods())
{
- // look for a seam managed persistence unit declaration on EE resource
- // producer fields
if (m.isAnnotationPresent(SeamManaged.class) && m.isAnnotationPresent(Produces.class) && EntityManagerFactory.class.isAssignableFrom(m.getJavaMember().getReturnType()))
{
if (modifiedType == null)
@@ -145,51 +161,34 @@
qualifiers.add(new DefaultLiteral());
}
qualifiers.add(AnyLiteral.INSTANCE);
- // we need to remove the scope, they are not nessesarily supported
- // on producer fields
+ // we need to change the scope to application scoped
modifiedType.removeFromMethod(m.getJavaMember(), scope);
modifiedType.addToMethod(m.getJavaMember(), ApplicationScopedLiteral.INSTANCE);
registerManagedPersistenceContext(qualifiers, scope, manager, event.getAnnotatedType().getJavaClass().getClassLoader());
}
- // now look for producer methods that produce an EntityManagerFactory.
- // This allows the user to manually configure an EntityManagerFactory
- // and return it from a producer method
}
if (modifiedType != null)
{
event.setAnnotatedType(modifiedType.create());
}
- // prevent the install of HibernatePersistenceProvider is hibernate is not
- // present
- if (event.getAnnotatedType().getJavaClass() == HibernatePersistenceProvider.class)
- {
- try
- {
- if (Thread.currentThread().getContextClassLoader() != null)
- {
- Thread.currentThread().getContextClassLoader().loadClass("org.hibernate.Session");
- }
- else
- {
- Class.forName("org.hibernate.Session");
- }
- }
- catch (ClassNotFoundException e)
- {
- event.veto();
- log.debug("Hibernate is not availbile", e);
- }
- }
}
- public void registerManagedPersistenceContext(Set<Annotation> qualifiers, Class<? extends Annotation> scope, BeanManager manager, ClassLoader loader)
+ private void registerManagedPersistenceContext(Set<Annotation> qualifiers, Class<? extends Annotation> scope, BeanManager manager, ClassLoader loader)
{
- // TODO: this is a massive hack. We need a much better way of doing this
- HibernatePersistenceProvider prov = new HibernatePersistenceProvider();
- Set<Class<?>> additionalInterfaces = prov.getAdditionalEntityManagerInterfaces();
+ // we need to add all additional interfaces from our
+ // SeamPersistenceProvider to the bean as at this stage we have no way of
+ // knowing which persistence provider is actually in use this only time
+ // that this may cause slightly odd behaviour is if two providers are on
+ // the class path, in which case the entity manager may be assignable to
+ // additional interfaces that it does not support.
+ Set<Class<?>> additionalInterfaces = new HashSet<Class<?>>();
+ for (SeamPersistenceProvider i : persistenceProviders)
+ {
+ additionalInterfaces.addAll(i.getAdditionalEntityManagerInterfaces());
+ }
// create the new bean to be registered later
- ManagedPersistenceContextBeanLifecycle lifecycle = new ManagedPersistenceContextBeanLifecycle(qualifiers, loader, manager, additionalInterfaces);
+ ManagedPersistenceContextBeanLifecycle lifecycle = new ManagedPersistenceContextBeanLifecycle(qualifiers, loader, manager, additionalInterfaces, persistenceProviders);
AnnotatedTypeBuilder<EntityManager> typeBuilder = new AnnotatedTypeBuilder().setJavaClass(EntityManager.class);
BeanBuilder<EntityManager> builder = new BeanBuilder<EntityManager>(manager).defineBeanFromAnnotatedType(typeBuilder.create());
builder.setQualifiers(qualifiers);
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextProxyHandler.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextProxyHandler.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/ManagedPersistenceContextProxyHandler.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -65,9 +65,9 @@
static final Logger log = LoggerFactory.getLogger(ManagedPersistenceContextProxyHandler.class);
- public ManagedPersistenceContextProxyHandler(EntityManager delegate, BeanManager beanManager, Set<Annotation> qualifiers, PersistenceContexts persistenceContexts)
+ public ManagedPersistenceContextProxyHandler(EntityManager delegate, BeanManager beanManager, Set<Annotation> qualifiers, PersistenceContexts persistenceContexts, SeamPersistenceProvider provider)
{
- super(delegate, beanManager, qualifiers);
+ super(delegate, beanManager, qualifiers, provider);
this.delegate = delegate;
this.userTransactionInstance = InstanceResolver.getInstance(SeamTransaction.class, beanManager, DefaultTransactionLiteral.INSTANCE);
this.persistenceContexts = persistenceContexts;
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/PersistenceContextProxyHandler.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/PersistenceContextProxyHandler.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/PersistenceContextProxyHandler.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -55,17 +55,20 @@
private final Instance<Expressions> expressionsInstance;
- private final Instance<SeamPersistenceProvider> persistenceProvider;
+ private final Instance<DefaultPersistenceProvider> persistenceProvider;
private final Set<Annotation> qualifiers;
+ private final SeamPersistenceProvider provider;
+
static final Logger log = LoggerFactory.getLogger(ManagedPersistenceContextProxyHandler.class);
- public PersistenceContextProxyHandler(EntityManager delegate, BeanManager beanManager, Set<Annotation> qualifiers)
+ public PersistenceContextProxyHandler(EntityManager delegate, BeanManager beanManager, Set<Annotation> qualifiers, SeamPersistenceProvider provider)
{
this.delegate = delegate;
+ this.provider = provider;
expressionsInstance = InstanceResolver.getInstance(Expressions.class, beanManager);
- persistenceProvider = InstanceResolver.getInstance(SeamPersistenceProvider.class, beanManager);
+ persistenceProvider = InstanceResolver.getInstance(DefaultPersistenceProvider.class, beanManager);
this.qualifiers = new HashSet<Annotation>(qualifiers);
}
@@ -88,6 +91,10 @@
{
return Collections.unmodifiableSet(qualifiers);
}
+ if ("getPersistenceProvider".equals(method.getName()) && method.getParameterTypes().length == 0)
+ {
+ return provider;
+ }
return method.invoke(delegate, args);
}
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/PersistenceContextsImpl.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/PersistenceContextsImpl.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/PersistenceContextsImpl.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -47,7 +47,7 @@
Instance<ManagedPersistenceContext> persistenceContexts;
@Inject
- Instance<SeamPersistenceProvider> persistenceProvider;
+ Instance<DefaultPersistenceProvider> persistenceProvider;
@Inject
public void create(FlushModeManager manager)
@@ -110,10 +110,10 @@
private void changeFlushModes()
{
-
for (ManagedPersistenceContext context : persistenceContexts)
{
if (set.contains(new PersistenceContextDefintition(context.getQualifiers(), context.getBeanType())))
+ {
try
{
context.changeFlushMode(flushMode);
@@ -124,14 +124,28 @@
// warning to the developer
log.warn(uoe.getMessage());
}
+ }
}
}
public void beforeRender()
{
- // some JPA providers may not support MANUAL flushing
- // defer the decision to the provider manager component
- persistenceProvider.get().setRenderFlushMode();
+ for (ManagedPersistenceContext context : persistenceContexts)
+ {
+ if (set.contains(new PersistenceContextDefintition(context.getQualifiers(), context.getBeanType())))
+ {
+ try
+ {
+ context.changeFlushMode(context.getProvider().getRenderFlushMode());
+ }
+ catch (UnsupportedOperationException uoe)
+ {
+ // we won't be nasty and throw and exception, but we'll log a
+ // warning to the developer
+ log.warn(uoe.getMessage());
+ }
+ }
+ }
}
public void afterRender()
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/SeamPersistenceProvider.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/SeamPersistenceProvider.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/SeamPersistenceProvider.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -1,137 +1,47 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2010, Red Hat, Inc., and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
package org.jboss.seam.persistence;
import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.Date;
-import java.util.HashSet;
import java.util.Set;
import javax.persistence.EntityManager;
-import javax.persistence.OptimisticLockException;
-import javax.persistence.PersistenceContexts;
import javax.transaction.Synchronization;
import org.jboss.seam.persistence.transaction.FlushModeType;
-import org.jboss.weld.extensions.defaultbean.DefaultBean;
/**
- * Abstraction layer for persistence providers (JPA implementations). This class
- * provides a working base implementation that can be optimized for performance
- * and non-standardized features by extending and overriding the methods.
+ * The interface can be implemented to provide extra functionality to a seam
+ * managed persistence context.
*
- * The methods on this class are a great todo list for the next rev of the JPA
- * spec ;-)
+ * seam-persistence contains a default implementation and a hinbernate based
+ * implementation.
*
- * @author Gavin King
- * @author Pete Muir
* @author Stuart Douglas
*
*/
- at DefaultBean(type = SeamPersistenceProvider.class)
-public class SeamPersistenceProvider
+public interface SeamPersistenceProvider
{
- public enum Feature
- {
- /**
- * Identifies whether this JPA provider supports using a wildcard as the
- * subject of a count query.
- *
- * <p>
- * Here's a count query that uses a wildcard as the subject.
- * </p>
- *
- * <pre>
- * select count(*) from Vehicle v
- * </pre>
- * <p>
- * Per the JPA 1.0 spec, using a wildcard as a subject of a count query is
- * not permitted. Instead, the subject must be the entity or the alias, as
- * in this count query:
- * </p>
- *
- * <pre>
- * select count(v) from Vehicle v
- * </pre>
- * <p>
- * Hibernate supports the wildcard syntax as an vendor extension.
- * Furthermore, Hibernate produces an invalid SQL query when using the
- * compliant subject if the entity has a composite primary key. Therefore,
- * we prefer to use the wildcard syntax if it is supported.
- * </p>
- */
- WILDCARD_AS_COUNT_QUERY_SUBJECT
- }
- protected Set<Feature> featureSet = new HashSet<Feature>();
-
/**
- * Indicate whether this JPA provider supports the feature defined by the
- * provided Feature enum value.
+ * sets the flush mode
*/
- public boolean supportsFeature(Feature feature)
- {
- return featureSet.contains(feature);
- }
+ public abstract void setFlushMode(EntityManager entityManager, FlushModeType type);
/**
- * sets the flush mode
+ * Should return true if this is the correct persistence provider for the
+ * given entity manager factory
+ *
*/
- public void setFlushMode(EntityManager entityManager, FlushModeType type)
- {
- switch (type)
- {
- case AUTO:
- entityManager.setFlushMode(javax.persistence.FlushModeType.AUTO);
- break;
- case COMMIT:
- entityManager.setFlushMode(javax.persistence.FlushModeType.COMMIT);
- break;
- case MANUAL:
- setFlushModeManual(entityManager);
- break;
- default:
- throw new RuntimeException("Unkown flush mode: " + type);
- }
- }
+ public abstract boolean isCorrectProvider(EntityManager em);
/**
* Set the flush mode to manual-only flushing. Called when an atomic
* persistence context is required.
*/
- public void setFlushModeManual(EntityManager entityManager)
- {
- throw new UnsupportedOperationException("Use of FlushMode.MANUAL requires Hibernate as the persistence provider. Please use Hibernate, a custom persistenceProvider, or remove the MANUAL flush mode setting.");
- }
+ public abstract void setFlushModeManual(EntityManager entityManager);
/**
* <p>
- * Set the FlushMode the persistence contexts should use during rendering by
- * calling {@link PersistenceContexts#changeFlushMode(FlushModeType, true)}.
- * The actual changing of the flush mode is handled by the
- * {@link PersistenceContexts} instance. The boolean argument should be true
- * to indicate that this is a temporary change and that the old flush mode
- * should be restored after render.
+ * Gets the FlushMode the persistence contexts should use during rendering
* </p>
* <p>
* Ideally, this should be MANUAL since changes should never flush to the
@@ -140,10 +50,7 @@
* specification, the default implementation will perform no operation.
* </p>
*/
- public void setRenderFlushMode()
- {
- // no-op in default implementation
- }
+ public abstract FlushModeType getRenderFlushMode();
/**
* Does the persistence context have unflushed changes? If it does not,
@@ -151,21 +58,14 @@
*
* @return true to indicate that there are unflushed changes
*/
- public boolean isDirty(EntityManager entityManager)
- {
- return true; // best we can do!
- }
+ public abstract boolean isDirty(EntityManager entityManager);
/**
* Get the value of the entity identifier attribute.
*
* @param bean a managed entity instance
*/
- public Object getId(Object bean, EntityManager entityManager)
- {
- // return Entity.forBean(bean).getIdentifier(bean);
- return null;
- }
+ public abstract Object getId(Object bean, EntityManager entityManager);
/**
* Get the name of the entity
@@ -175,39 +75,16 @@
*
* @throws IllegalArgumentException if the passed object is not an entity
*/
- public String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException
- {
- return null;
- // return Entity.forBean(bean).getName();
- }
+ public abstract String getName(Object bean, EntityManager entityManager) throws IllegalArgumentException;
/**
* Get the value of the entity version attribute.
*
* @param bean a managed entity instance
*/
- public Object getVersion(Object bean, EntityManager entityManager)
- {
- return null;
- // return Entity.forBean(bean).getVersion(bean);
- }
+ public abstract Object getVersion(Object bean, EntityManager entityManager);
- public void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version)
- {
- boolean equal;
- if (oldVersion instanceof Date)
- {
- equal = ((Date) oldVersion).getTime() == ((Date) version).getTime();
- }
- else
- {
- equal = oldVersion.equals(version);
- }
- if (!equal)
- {
- throw new OptimisticLockException("Current database version number does not match passivated version number");
- }
- }
+ public abstract void checkVersion(Object bean, EntityManager entityManager, Object oldVersion, Object version);
/**
* Enable a Filter. This is here just especially for Hibernate, since we well
@@ -220,28 +97,16 @@
/**
* Register a Synchronization with the current transaction.
*/
- public boolean registerSynchronization(Synchronization sync, EntityManager entityManager)
- {
- return false; // best we can do!
- }
+ public abstract boolean registerSynchronization(Synchronization sync, EntityManager entityManager);
/**
* Wrap the delegate before returning it to the application
*/
- public Object proxyDelegate(Object delegate)
- {
- return delegate;
- }
+ public abstract Object proxyDelegate(Object delegate);
- public EntityManager proxyEntityManager(EntityManager entityManager)
- {
- return entityManager;
- }
+ public abstract EntityManager proxyEntityManager(EntityManager entityManager);
- public Set<Class<?>> getAdditionalEntityManagerInterfaces()
- {
- return Collections.emptySet();
- }
+ public abstract Set<Class<?>> getAdditionalEntityManagerInterfaces();
/**
* Returns the class of an entity bean instance
@@ -249,34 +114,14 @@
* @param bean The entity bean instance
* @return The class of the entity bean
*/
- public Class getBeanClass(Object bean)
- {
- return null;
- // return Entity.forBean(bean).getBeanClass();
- }
+ public abstract Class<?> getBeanClass(Object bean);
- public Method getPostLoadMethod(Object bean, EntityManager entityManager)
- {
- return null;
- // return Entity.forBean(bean).getPostLoadMethod();
- }
+ public abstract Method getPostLoadMethod(Object bean, EntityManager entityManager);
- public Method getPrePersistMethod(Object bean, EntityManager entityManager)
- {
- return null;
- // return Entity.forBean(bean).getPrePersistMethod();
- }
+ public abstract Method getPrePersistMethod(Object bean, EntityManager entityManager);
- public Method getPreUpdateMethod(Object bean, EntityManager entityManager)
- {
- return null;
- // return Entity.forBean(bean).getPreUpdateMethod();
- }
+ public abstract Method getPreUpdateMethod(Object bean, EntityManager entityManager);
- public Method getPreRemoveMethod(Object bean, EntityManager entityManager)
- {
- return null;
- // return Entity.forBean(bean).getPreRemoveMethod();
- }
+ public abstract Method getPreRemoveMethod(Object bean, EntityManager entityManager);
-}
+}
\ No newline at end of file
Modified: modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/EntityTransaction.java
===================================================================
--- modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/EntityTransaction.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/main/java/org/jboss/seam/persistence/transaction/EntityTransaction.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -33,7 +33,7 @@
import javax.transaction.Synchronization;
import javax.transaction.SystemException;
-import org.jboss.seam.persistence.SeamPersistenceProvider;
+import org.jboss.seam.persistence.DefaultPersistenceProvider;
import org.jboss.weld.extensions.core.Veto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -58,7 +58,7 @@
private EntityManager entityManager;
@Inject
- private Instance<SeamPersistenceProvider> persistenceProvider;
+ private Instance<DefaultPersistenceProvider> persistenceProvider;
@Inject
public void init(Synchronizations sync)
Added: modules/persistence/trunk/impl/src/main/resources/META-INF/services/org.jboss.seam.persistence.SeamPersistenceProvider
===================================================================
--- modules/persistence/trunk/impl/src/main/resources/META-INF/services/org.jboss.seam.persistence.SeamPersistenceProvider (rev 0)
+++ modules/persistence/trunk/impl/src/main/resources/META-INF/services/org.jboss.seam.persistence.SeamPersistenceProvider 2010-08-30 23:56:10 UTC (rev 13669)
@@ -0,0 +1 @@
+org.jboss.seam.persistence.HibernatePersistenceProvider
\ No newline at end of file
Modified: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/test/HibernateSearchTest.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/test/HibernateSearchTest.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/test/HibernateSearchTest.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -73,6 +73,7 @@
war.addWebResource("META-INF/persistence-search.xml", "classes/META-INF/persistence.xml");
war.addWebResource(new ByteArrayAsset(new byte[0]), "beans.xml");
war.addWebResource("META-INF/services/javax.enterprise.inject.spi.Extension", "classes/META-INF/services/javax.enterprise.inject.spi.Extension");
+ war.addWebResource("META-INF/services/org.jboss.seam.persistence.SeamPersistenceProvider", "classes/META-INF/services/org.jboss.seam.persistence.SeamPersistenceProvider");
return war;
}
Modified: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/test/ManagedPersistenceContextFlushModeTest.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/test/ManagedPersistenceContextFlushModeTest.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/test/ManagedPersistenceContextFlushModeTest.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -73,6 +73,7 @@
war.addWebResource("META-INF/persistence.xml", "classes/META-INF/persistence.xml");
war.addWebResource(new ByteArrayAsset(new byte[0]), "beans.xml");
war.addWebResource("META-INF/services/javax.enterprise.inject.spi.Extension", "classes/META-INF/services/javax.enterprise.inject.spi.Extension");
+ war.addWebResource("META-INF/services/org.jboss.seam.persistence.SeamPersistenceProvider", "classes/META-INF/services/org.jboss.seam.persistence.SeamPersistenceProvider");
return war;
}
Modified: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionAttributeInterceptorTest.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -37,7 +37,7 @@
import org.jboss.arquillian.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.seam.persistence.SeamPersistenceProvider;
+import org.jboss.seam.persistence.DefaultPersistenceProvider;
import org.jboss.seam.persistence.transaction.DefaultTransaction;
import org.jboss.seam.persistence.transaction.SeamTransaction;
import org.jboss.seam.persistence.transaction.TransactionExtension;
@@ -76,7 +76,7 @@
war.addLibraries(MavenArtifactResolver.resolve(ArtifactNames.WELD_EXTENSIONS));
war.addLibraries(MavenArtifactResolver.resolve(ArtifactNames.SEAM_PERSISTENCE_API));
war.addPackage(TransactionExtension.class.getPackage());
- war.addPackage(SeamPersistenceProvider.class.getPackage());
+ war.addPackage(DefaultPersistenceProvider.class.getPackage());
war.addPackage(TransactionScopeExtension.class.getPackage());
war.addPackage(NamingUtils.class.getPackage());
war.addClasses(TransactionAttributeInterceptorTest.class, TransactionAttributeManagedBean.class, HelloService.class, Hotel.class, EntityManagerProvider.class, DontRollBackException.class);
Modified: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionInterceptorTest.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -37,7 +37,7 @@
import org.jboss.arquillian.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.seam.persistence.SeamPersistenceProvider;
+import org.jboss.seam.persistence.DefaultPersistenceProvider;
import org.jboss.seam.persistence.transaction.DefaultTransaction;
import org.jboss.seam.persistence.transaction.SeamTransaction;
import org.jboss.seam.persistence.transaction.TransactionExtension;
@@ -78,7 +78,7 @@
war.addPackage(TransactionExtension.class.getPackage());
war.addPackage(TransactionScopeExtension.class.getPackage());
war.addPackage(NamingUtils.class.getPackage());
- war.addPackage(SeamPersistenceProvider.class.getPackage());
+ war.addPackage(DefaultPersistenceProvider.class.getPackage());
war.addClasses(TransactionInterceptorTest.class, TransactionManagedBean.class, HelloService.class, Hotel.class, EntityManagerProvider.class, DontRollBackException.class);
war.addWebResource("META-INF/persistence.xml", "classes/META-INF/persistence.xml");
war.addWebResource(new ByteArrayAsset(("<beans><interceptors><class>" + TransactionInterceptor.class.getName() + "</class></interceptors></beans>").getBytes()), "beans.xml");
Modified: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionScopedTest.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionScopedTest.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/TransactionScopedTest.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -13,7 +13,7 @@
import org.jboss.arquillian.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.seam.persistence.SeamPersistenceProvider;
+import org.jboss.seam.persistence.DefaultPersistenceProvider;
import org.jboss.seam.persistence.transaction.DefaultTransaction;
import org.jboss.seam.persistence.transaction.SeamTransaction;
import org.jboss.seam.persistence.transaction.TransactionExtension;
@@ -41,7 +41,7 @@
war.addLibraries(MavenArtifactResolver.resolve(ArtifactNames.SEAM_PERSISTENCE_API));
war.addPackage(TransactionExtension.class.getPackage());
war.addPackage(TransactionScopeExtension.class.getPackage());
- war.addPackage(SeamPersistenceProvider.class.getPackage());
+ war.addPackage(DefaultPersistenceProvider.class.getPackage());
war.addPackage(NamingUtils.class.getPackage());
war.addClasses(TransactionScopedTest.class, Hotel.class, HelloService.class, TransactionScopedObject.class);
war.addWebResource("META-INF/persistence.xml", "classes/META-INF/persistence.xml");
Modified: modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/UserTransactionTest.java
===================================================================
--- modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/UserTransactionTest.java 2010-08-30 22:33:36 UTC (rev 13668)
+++ modules/persistence/trunk/impl/src/test/java/org/jboss/seam/persistence/transactions/test/UserTransactionTest.java 2010-08-30 23:56:10 UTC (rev 13669)
@@ -15,7 +15,6 @@
import org.jboss.arquillian.api.Deployment;
import org.jboss.arquillian.junit.Arquillian;
-import org.jboss.seam.persistence.SeamPersistenceProvider;
import org.jboss.seam.persistence.transaction.DefaultTransaction;
import org.jboss.seam.persistence.transaction.SeamTransaction;
import org.jboss.seam.persistence.transaction.TransactionExtension;
@@ -42,7 +41,6 @@
war.addLibraries(MavenArtifactResolver.resolve(ArtifactNames.SEAM_PERSISTENCE_API));
war.addPackage(TransactionExtension.class.getPackage());
war.addClasses(UserTransactionTest.class, Hotel.class, HelloService.class);
- war.addClass(SeamPersistenceProvider.class);
war.addPackage(NamingUtils.class.getPackage());
war.addWebResource("META-INF/persistence.xml", "classes/META-INF/persistence.xml");
war.addWebResource(new ByteArrayAsset(new byte[0]), "beans.xml");
More information about the seam-commits
mailing list