Skip to content

Commit

Permalink
WFLY-5071 Remove static fields from the JPA subsystem
Browse files Browse the repository at this point in the history
  • Loading branch information
stuartwdouglas committed Sep 3, 2015
1 parent 764983d commit 1cf5f1f
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 107 deletions.
Expand Up @@ -24,13 +24,22 @@


import static org.jboss.as.jpa.messages.JpaLogger.ROOT_LOGGER; import static org.jboss.as.jpa.messages.JpaLogger.ROOT_LOGGER;


import java.io.IOException;
import java.io.Serializable; import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;


import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.SynchronizationType; import javax.persistence.SynchronizationType;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;


import org.jboss.as.jpa.messages.JpaLogger; import org.jboss.as.jpa.messages.JpaLogger;
import org.jboss.as.jpa.transaction.TransactionUtil; import org.jboss.as.jpa.transaction.TransactionUtil;
import org.jboss.as.server.CurrentServiceContainer;
import org.jboss.as.txn.service.TransactionManagerService;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.wildfly.security.manager.WildFlySecurityManager;


/** /**
* Represents the Extended persistence context injected into a stateful bean. At bean invocation time, * Represents the Extended persistence context injected into a stateful bean. At bean invocation time,
Expand Down Expand Up @@ -92,11 +101,15 @@ public class ExtendedEntityManager extends AbstractEntityManager implements Seri
private final transient boolean isTraceEnabled = ROOT_LOGGER.isTraceEnabled(); private final transient boolean isTraceEnabled = ROOT_LOGGER.isTraceEnabled();


private final SynchronizationType synchronizationType; private final SynchronizationType synchronizationType;
private transient TransactionSynchronizationRegistry transactionSynchronizationRegistry;
private transient TransactionManager transactionManager;


public ExtendedEntityManager(final String puScopedName, final EntityManager underlyingEntityManager, final SynchronizationType synchronizationType) { public ExtendedEntityManager(final String puScopedName, final EntityManager underlyingEntityManager, final SynchronizationType synchronizationType, TransactionSynchronizationRegistry transactionSynchronizationRegistry, TransactionManager transactionManager) {
this.underlyingEntityManager = underlyingEntityManager; this.underlyingEntityManager = underlyingEntityManager;
this.puScopedName = puScopedName; this.puScopedName = puScopedName;
this.synchronizationType = synchronizationType; this.synchronizationType = synchronizationType;
this.transactionSynchronizationRegistry = transactionSynchronizationRegistry;
this.transactionManager = transactionManager;
} }


/** /**
Expand All @@ -123,14 +136,14 @@ protected EntityManager getEntityManager() {
* this method is private to the JPA subsystem * this method is private to the JPA subsystem
*/ */
public void internalAssociateWithJtaTx() { public void internalAssociateWithJtaTx() {
isInTx = TransactionUtil.isInTx(); isInTx = TransactionUtil.isInTx(transactionManager);


// ensure that a different XPC (with same name) is not already present in the TX // ensure that a different XPC (with same name) is not already present in the TX
if (isInTx) { if (isInTx) {


// 7.6.3.1 throw EJBException if a different persistence context is already joined to the // 7.6.3.1 throw EJBException if a different persistence context is already joined to the
// transaction (with the same puScopedName). // transaction (with the same puScopedName).
EntityManager existing = TransactionUtil.getTransactionScopedEntityManager(puScopedName); EntityManager existing = TransactionUtil.getTransactionScopedEntityManager(puScopedName, transactionSynchronizationRegistry);
if (existing != null && existing != this) { if (existing != null && existing != this) {
// should be enough to test if not the same object // should be enough to test if not the same object
throw JpaLogger.ROOT_LOGGER.cannotUseExtendedPersistenceTransaction(puScopedName, existing, this); throw JpaLogger.ROOT_LOGGER.cannotUseExtendedPersistenceTransaction(puScopedName, existing, this);
Expand All @@ -141,7 +154,7 @@ public void internalAssociateWithJtaTx() {
underlyingEntityManager.joinTransaction(); underlyingEntityManager.joinTransaction();
} }
// associate the entity manager with the current transaction // associate the entity manager with the current transaction
TransactionUtil.putEntityManagerInTransactionRegistry(puScopedName, this); TransactionUtil.putEntityManagerInTransactionRegistry(puScopedName, this, transactionSynchronizationRegistry);
} }
} }
} }
Expand Down Expand Up @@ -256,4 +269,21 @@ public SynchronizationType getSynchronizationType() {
protected boolean deferEntityDetachUntilClose() { protected boolean deferEntityDetachUntilClose() {
return false; return false;
} }

private void readObject(java.io.ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
if(WildFlySecurityManager.isChecking()) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
transactionManager = (TransactionManager) CurrentServiceContainer.getServiceContainer().getService(TransactionManagerService.SERVICE_NAME).getValue();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) CurrentServiceContainer.getServiceContainer().getService(TransactionSynchronizationRegistryService.SERVICE_NAME).getValue();
return null;
}
});
} else {
transactionManager = (TransactionManager) CurrentServiceContainer.getServiceContainer().getService(TransactionManagerService.SERVICE_NAME).getValue();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) CurrentServiceContainer.getServiceContainer().getService(TransactionSynchronizationRegistryService.SERVICE_NAME).getValue();
}
}
} }
Expand Up @@ -32,13 +32,17 @@
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.SynchronizationType; import javax.persistence.SynchronizationType;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;


import org.jboss.as.jpa.config.Configuration; import org.jboss.as.jpa.config.Configuration;
import org.jboss.as.jpa.messages.JpaLogger; import org.jboss.as.jpa.messages.JpaLogger;
import org.jboss.as.jpa.service.PersistenceUnitServiceImpl; import org.jboss.as.jpa.service.PersistenceUnitServiceImpl;
import org.jboss.as.jpa.transaction.TransactionUtil; import org.jboss.as.jpa.transaction.TransactionUtil;
import org.jboss.as.jpa.util.JPAServiceNames; import org.jboss.as.jpa.util.JPAServiceNames;
import org.jboss.as.server.CurrentServiceContainer; import org.jboss.as.server.CurrentServiceContainer;
import org.jboss.as.txn.service.TransactionManagerService;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.jboss.msc.service.ServiceContainer; import org.jboss.msc.service.ServiceContainer;
import org.jboss.msc.service.ServiceController; import org.jboss.msc.service.ServiceController;


Expand All @@ -59,21 +63,25 @@ public class TransactionScopedEntityManager extends AbstractEntityManager implem
private final Map properties; private final Map properties;
private transient EntityManagerFactory emf; private transient EntityManagerFactory emf;
private final SynchronizationType synchronizationType; private final SynchronizationType synchronizationType;
private transient TransactionSynchronizationRegistry transactionSynchronizationRegistry;
private transient TransactionManager transactionManager;
private transient Boolean deferDetach; private transient Boolean deferDetach;


public TransactionScopedEntityManager(String puScopedName, Map properties, EntityManagerFactory emf, SynchronizationType synchronizationType) { public TransactionScopedEntityManager(String puScopedName, Map properties, EntityManagerFactory emf, SynchronizationType synchronizationType, TransactionSynchronizationRegistry transactionSynchronizationRegistry, TransactionManager transactionManager) {
this.puScopedName = puScopedName; this.puScopedName = puScopedName;
this.properties = properties; this.properties = properties;
this.emf = emf; this.emf = emf;
this.synchronizationType = synchronizationType; this.synchronizationType = synchronizationType;
this.transactionSynchronizationRegistry = transactionSynchronizationRegistry;
this.transactionManager = transactionManager;
} }


@Override @Override
protected EntityManager getEntityManager() { protected EntityManager getEntityManager() {
EntityManager entityManager; EntityManager entityManager;
boolean isInTx; boolean isInTx;


isInTx = TransactionUtil.isInTx(); isInTx = TransactionUtil.isInTx(transactionManager);


if (isInTx) { if (isInTx) {
entityManager = getOrCreateTransactionScopedEntityManager(emf, puScopedName, properties, synchronizationType); entityManager = getOrCreateTransactionScopedEntityManager(emf, puScopedName, properties, synchronizationType);
Expand All @@ -94,7 +102,7 @@ protected boolean isExtendedPersistenceContext() {


@Override @Override
protected boolean isInTx() { protected boolean isInTx() {
return TransactionUtil.isInTx(); return TransactionUtil.isInTx(transactionManager);
} }


/** /**
Expand All @@ -111,6 +119,9 @@ private void readObject(java.io.ObjectInputStream in) throws IOException, ClassN
in.defaultReadObject(); in.defaultReadObject();
final ServiceController<?> controller = currentServiceContainer().getService(JPAServiceNames.getPUServiceName(puScopedName)); final ServiceController<?> controller = currentServiceContainer().getService(JPAServiceNames.getPUServiceName(puScopedName));
final PersistenceUnitServiceImpl persistenceUnitService = (PersistenceUnitServiceImpl) controller.getService(); final PersistenceUnitServiceImpl persistenceUnitService = (PersistenceUnitServiceImpl) controller.getService();
transactionManager = (TransactionManager) currentServiceContainer().getService(TransactionManagerService.SERVICE_NAME).getValue();
transactionSynchronizationRegistry = (TransactionSynchronizationRegistry) currentServiceContainer().getService(TransactionSynchronizationRegistryService.SERVICE_NAME).getValue();

emf = persistenceUnitService.getEntityManagerFactory(); emf = persistenceUnitService.getEntityManagerFactory();
} }


Expand Down Expand Up @@ -141,20 +152,21 @@ private EntityManager getOrCreateTransactionScopedEntityManager(
final String scopedPuName, final String scopedPuName,
final Map properties, final Map properties,
final SynchronizationType synchronizationType) { final SynchronizationType synchronizationType) {
EntityManager entityManager = TransactionUtil.getTransactionScopedEntityManager(puScopedName); EntityManager entityManager = TransactionUtil.getTransactionScopedEntityManager(puScopedName, transactionSynchronizationRegistry);
if (entityManager == null) { if (entityManager == null) {
entityManager = createEntityManager(emf, properties, synchronizationType); entityManager = createEntityManager(emf, properties, synchronizationType);
if (ROOT_LOGGER.isDebugEnabled()) if (ROOT_LOGGER.isDebugEnabled()) {
ROOT_LOGGER.debugf("%s: created entity manager session %s", TransactionUtil.getEntityManagerDetails(entityManager, scopedPuName), ROOT_LOGGER.debugf("%s: created entity manager session %s", TransactionUtil.getEntityManagerDetails(entityManager, scopedPuName),
TransactionUtil.getTransaction().toString()); TransactionUtil.getTransaction(transactionManager).toString());
TransactionUtil.registerSynchronization(entityManager, scopedPuName); }
TransactionUtil.putEntityManagerInTransactionRegistry(scopedPuName, entityManager); TransactionUtil.registerSynchronization(entityManager, scopedPuName, transactionSynchronizationRegistry);
TransactionUtil.putEntityManagerInTransactionRegistry(scopedPuName, entityManager, transactionSynchronizationRegistry);
} }
else { else {
testForMixedSynchronizationTypes(entityManager, puScopedName, synchronizationType); testForMixedSynchronizationTypes(entityManager, puScopedName, synchronizationType);
if (ROOT_LOGGER.isDebugEnabled()) { if (ROOT_LOGGER.isDebugEnabled()) {
ROOT_LOGGER.debugf("%s: reuse entity manager session already in tx %s", TransactionUtil.getEntityManagerDetails(entityManager, scopedPuName), ROOT_LOGGER.debugf("%s: reuse entity manager session already in tx %s", TransactionUtil.getEntityManagerDetails(entityManager, scopedPuName),
TransactionUtil.getTransaction().toString()); TransactionUtil.getTransaction(transactionManager).toString());
} }
} }
return entityManager; return entityManager;
Expand Down Expand Up @@ -197,6 +209,4 @@ private static void testForMixedSynchronizationTypes(EntityManager entityManager
throw JpaLogger.ROOT_LOGGER.badSynchronizationTypeCombination(scopedPuName); throw JpaLogger.ROOT_LOGGER.badSynchronizationTypeCombination(scopedPuName);
} }
} }


} }
Expand Up @@ -31,6 +31,8 @@
import javax.persistence.EntityManagerFactory; import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContextType; import javax.persistence.PersistenceContextType;
import javax.persistence.SynchronizationType; import javax.persistence.SynchronizationType;
import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;


import org.jboss.as.ee.component.InjectionSource; import org.jboss.as.ee.component.InjectionSource;
import org.jboss.as.jpa.config.ExtendedPersistenceInheritance; import org.jboss.as.jpa.config.ExtendedPersistenceInheritance;
Expand All @@ -49,6 +51,8 @@
import org.jboss.as.naming.ValueManagedReference; import org.jboss.as.naming.ValueManagedReference;
import org.jboss.as.server.deployment.DeploymentPhaseContext; import org.jboss.as.server.deployment.DeploymentPhaseContext;
import org.jboss.as.server.deployment.DeploymentUnitProcessingException; import org.jboss.as.server.deployment.DeploymentUnitProcessingException;
import org.jboss.as.txn.service.TransactionManagerService;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.jboss.msc.inject.Injector; import org.jboss.msc.inject.Injector;
import org.jboss.msc.service.ServiceBuilder; import org.jboss.msc.service.ServiceBuilder;
import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceName;
Expand Down Expand Up @@ -150,9 +154,12 @@ public ManagedReference getReference() {
EntityManagerFactory emf = service.getEntityManagerFactory(); EntityManagerFactory emf = service.getEntityManagerFactory();
EntityManager entityManager; EntityManager entityManager;
boolean standardEntityManager = ENTITY_MANAGER_CLASS.equals(injectionTypeName); boolean standardEntityManager = ENTITY_MANAGER_CLASS.equals(injectionTypeName);

//TODO: change all this to use injections
//this is currntly safe, as there is a DUP dependency on the TSR
TransactionSynchronizationRegistry tsr = (TransactionSynchronizationRegistry) serviceRegistry.getRequiredService(TransactionSynchronizationRegistryService.SERVICE_NAME).getValue();
TransactionManager transactionManager = (TransactionManager) serviceRegistry.getRequiredService(TransactionManagerService.SERVICE_NAME).getValue();
if (type.equals(PersistenceContextType.TRANSACTION)) { if (type.equals(PersistenceContextType.TRANSACTION)) {
entityManager = new TransactionScopedEntityManager(unitName, properties, emf, synchronizationType); entityManager = new TransactionScopedEntityManager(unitName, properties, emf, synchronizationType, tsr, transactionManager);
if (ROOT_LOGGER.isDebugEnabled()) if (ROOT_LOGGER.isDebugEnabled())
ROOT_LOGGER.debugf("created new TransactionScopedEntityManager for unit name=%s", unitName); ROOT_LOGGER.debugf("created new TransactionScopedEntityManager for unit name=%s", unitName);
} else { } else {
Expand All @@ -173,10 +180,10 @@ public ManagedReference getReference() {


if (entityManager1 == null) { if (entityManager1 == null) {
if (SynchronizationType.UNSYNCHRONIZED.equals(synchronizationType)) { if (SynchronizationType.UNSYNCHRONIZED.equals(synchronizationType)) {
entityManager1 = new ExtendedEntityManager(unitName, emf.createEntityManager(synchronizationType, properties), synchronizationType); entityManager1 = new ExtendedEntityManager(unitName, emf.createEntityManager(synchronizationType, properties), synchronizationType, tsr, transactionManager);
} }
else { else {
entityManager1 = new ExtendedEntityManager(unitName, emf.createEntityManager(properties), synchronizationType); entityManager1 = new ExtendedEntityManager(unitName, emf.createEntityManager(properties), synchronizationType, tsr, transactionManager);
} }
createdNewExtendedPersistence = true; createdNewExtendedPersistence = true;
if (ROOT_LOGGER.isDebugEnabled()) if (ROOT_LOGGER.isDebugEnabled())
Expand Down
Expand Up @@ -26,6 +26,9 @@
import org.jboss.as.server.deployment.AttachmentKey; import org.jboss.as.server.deployment.AttachmentKey;
import org.jboss.msc.service.ServiceName; import org.jboss.msc.service.ServiceName;


import javax.transaction.TransactionManager;
import javax.transaction.TransactionSynchronizationRegistry;

/** /**
* @author Stuart Douglas * @author Stuart Douglas
* @author thomas.diesler@jboss.com * @author thomas.diesler@jboss.com
Expand All @@ -38,6 +41,9 @@ public final class JpaAttachments {


public static final AttachmentKey<ServiceName> PERSISTENCE_UNIT_SERVICE_KEY = AttachmentKey.create(ServiceName.class); public static final AttachmentKey<ServiceName> PERSISTENCE_UNIT_SERVICE_KEY = AttachmentKey.create(ServiceName.class);


public static final AttachmentKey<TransactionManager> TRANSACTION_MANAGER = AttachmentKey.create(TransactionManager.class);
public static final AttachmentKey<TransactionSynchronizationRegistry> TRANSACTION_SYNCHRONIZATION_REGISTRY= AttachmentKey.create(TransactionSynchronizationRegistry.class);

/** /**
* List<PersistenceUnitMetadataImpl> that represents the JPA persistent units * List<PersistenceUnitMetadataImpl> that represents the JPA persistent units
*/ */
Expand Down
Expand Up @@ -97,7 +97,7 @@ public void cleanup(PersistenceUnitMetadata pu) {
* @return the persistence provider adaptor for the provider class * @return the persistence provider adaptor for the provider class
* @throws ModuleLoadException * @throws ModuleLoadException
*/ */
public static PersistenceProviderAdaptor loadPersistenceAdapterModule(final String adapterModule, final Platform platform) throws public static PersistenceProviderAdaptor loadPersistenceAdapterModule(final String adapterModule, final Platform platform, JtaManagerImpl manager) throws
ModuleLoadException { ModuleLoadException {
final ModuleLoader moduleLoader = Module.getBootModuleLoader(); final ModuleLoader moduleLoader = Module.getBootModuleLoader();


Expand All @@ -119,7 +119,7 @@ public static PersistenceProviderAdaptor loadPersistenceAdapterModule(final Stri
ROOT_LOGGER.debugf("loaded persistence provider adapter %s", adapterModule); ROOT_LOGGER.debugf("loaded persistence provider adapter %s", adapterModule);
} }
if (persistenceProviderAdaptor != null) { if (persistenceProviderAdaptor != null) {
persistenceProviderAdaptor.injectJtaManager(JtaManagerImpl.getInstance()); persistenceProviderAdaptor.injectJtaManager(manager);
persistenceProviderAdaptor.injectPlatform(platform); persistenceProviderAdaptor.injectPlatform(platform);
} }
} }
Expand All @@ -133,7 +133,7 @@ public static PersistenceProviderAdaptor loadPersistenceAdapterModule(final Stri
* @param persistenceProvider classloader will be used to load the persistence provider adapter * @param persistenceProvider classloader will be used to load the persistence provider adapter
* @return the persistence provider adaptor for the provider class * @return the persistence provider adaptor for the provider class
*/ */
public static PersistenceProviderAdaptor loadPersistenceAdapter(final PersistenceProvider persistenceProvider, final Platform platform) public static PersistenceProviderAdaptor loadPersistenceAdapter(final PersistenceProvider persistenceProvider, final Platform platform, final JtaManagerImpl jtaManager)
{ {
PersistenceProviderAdaptor persistenceProviderAdaptor=null; PersistenceProviderAdaptor persistenceProviderAdaptor=null;


Expand All @@ -151,7 +151,7 @@ public static PersistenceProviderAdaptor loadPersistenceAdapter(final Persistenc
persistenceProvider.getClass().getClassLoader().toString()); persistenceProvider.getClass().getClassLoader().toString());
} }
if (persistenceProviderAdaptor != null) { if (persistenceProviderAdaptor != null) {
persistenceProviderAdaptor.injectJtaManager(JtaManagerImpl.getInstance()); persistenceProviderAdaptor.injectJtaManager(jtaManager);
persistenceProviderAdaptor.injectPlatform(platform); persistenceProviderAdaptor.injectPlatform(platform);
} }
} }
Expand Down
Expand Up @@ -86,7 +86,7 @@ public static void deploy(final DeploymentPhaseContext phaseContext, final Platf
if (adapterClass != null) { if (adapterClass != null) {
try { try {
adaptor = (PersistenceProviderAdaptor) deploymentModuleClassLoader.loadClass(adapterClass).newInstance(); adaptor = (PersistenceProviderAdaptor) deploymentModuleClassLoader.loadClass(adapterClass).newInstance();
adaptor.injectJtaManager(JtaManagerImpl.getInstance()); adaptor.injectJtaManager(new JtaManagerImpl(deploymentUnit.getAttachment(JpaAttachments.TRANSACTION_MANAGER), deploymentUnit.getAttachment(JpaAttachments.TRANSACTION_SYNCHRONIZATION_REGISTRY)));
adaptor.injectPlatform(platform); adaptor.injectPlatform(platform);
ArrayList<PersistenceProviderAdaptor> adaptorList = new ArrayList<>(); ArrayList<PersistenceProviderAdaptor> adaptorList = new ArrayList<>();
adaptorList.add(adaptor); adaptorList.add(adaptor);
Expand Down
Expand Up @@ -38,6 +38,8 @@
import org.jboss.as.server.deployment.JPADeploymentMarker; import org.jboss.as.server.deployment.JPADeploymentMarker;
import org.jboss.as.server.deployment.SubDeploymentMarker; import org.jboss.as.server.deployment.SubDeploymentMarker;
import org.jboss.as.server.deployment.module.ResourceRoot; import org.jboss.as.server.deployment.module.ResourceRoot;
import org.jboss.as.txn.service.TransactionManagerService;
import org.jboss.as.txn.service.TransactionSynchronizationRegistryService;
import org.jboss.metadata.parser.util.NoopXMLResolver; import org.jboss.metadata.parser.util.NoopXMLResolver;
import org.jboss.vfs.VirtualFile; import org.jboss.vfs.VirtualFile;
import org.jipijapa.plugin.spi.PersistenceUnitMetadata; import org.jipijapa.plugin.spi.PersistenceUnitMetadata;
Expand Down Expand Up @@ -89,6 +91,9 @@ public void deploy(DeploymentPhaseContext phaseContext) throws DeploymentUnitPro
handleWarDeployment(phaseContext); handleWarDeployment(phaseContext);
handleEarDeployment(phaseContext); handleEarDeployment(phaseContext);
handleJarDeployment(phaseContext); handleJarDeployment(phaseContext);

phaseContext.addDeploymentDependency(TransactionManagerService.SERVICE_NAME, JpaAttachments.TRANSACTION_MANAGER);
phaseContext.addDeploymentDependency(TransactionSynchronizationRegistryService.SERVICE_NAME, JpaAttachments.TRANSACTION_SYNCHRONIZATION_REGISTRY);
} }


@Override @Override
Expand Down

0 comments on commit 1cf5f1f

Please sign in to comment.