From 1044c365b8838d8387edeb4605ea0288864b222a Mon Sep 17 00:00:00 2001 From: Romain manni-Bucau Date: Wed, 10 Feb 2016 13:42:09 +0100 Subject: [PATCH] BATCHEE-94 adding EEEntityManagerProvider and EETransactionProvider --- .../JPAPersistenceManagerService.java | 9 ++- .../jpa/provider/EEEntityManagerProvider.java | 60 +++++++++++++++++++ .../jpa/provider/EETransactionProvider.java | 54 +++++++++++++++++ .../JTAUserTransactionAdapter.java | 24 ++++++++ 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 jbatch/src/main/java/org/apache/batchee/container/services/persistence/jpa/provider/EEEntityManagerProvider.java create mode 100644 jbatch/src/main/java/org/apache/batchee/container/services/persistence/jpa/provider/EETransactionProvider.java diff --git a/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java index a695327..90eea56 100644 --- a/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java +++ b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/JPAPersistenceManagerService.java @@ -37,6 +37,8 @@ import org.apache.batchee.container.services.persistence.jpa.domain.StepExecutionEntity; import org.apache.batchee.container.services.persistence.jpa.provider.DefaultEntityManagerProvider; import org.apache.batchee.container.services.persistence.jpa.provider.DefaultTransactionProvider; +import org.apache.batchee.container.services.persistence.jpa.provider.EEEntityManagerProvider; +import org.apache.batchee.container.services.persistence.jpa.provider.EETransactionProvider; import org.apache.batchee.container.status.JobStatus; import org.apache.batchee.container.status.StepStatus; import org.apache.batchee.spi.PersistenceManagerService; @@ -850,7 +852,9 @@ public CheckpointData getCheckpointData(final CheckpointDataKey key) { @Override public void init(final Properties batchConfig) { - final String txProviderClass = batchConfig.getProperty("persistence.jpa.transaction-provider", DefaultTransactionProvider.class.getName()); + final boolean ee = "true".equalsIgnoreCase(batchConfig.getProperty("persistence.jpa.ee", "false")); + final String txProviderClass = batchConfig.getProperty( + "persistence.jpa.transaction-provider", ee ? EETransactionProvider.class.getName() : DefaultTransactionProvider.class.getName()); try { txProvider = TransactionProvider.class.cast(Thread.currentThread().getContextClassLoader().loadClass(txProviderClass).newInstance()); } catch (final Exception e) { @@ -858,7 +862,8 @@ public void init(final Properties batchConfig) { } txProvider.init(batchConfig); - final String providerClass = batchConfig.getProperty("persistence.jpa.entity-manager-provider", DefaultEntityManagerProvider.class.getName()); + final String providerClass = batchConfig.getProperty( + "persistence.jpa.entity-manager-provider", ee ? EEEntityManagerProvider.class.getName() : DefaultEntityManagerProvider.class.getName()); try { emProvider = EntityManagerProvider.class.cast(Thread.currentThread().getContextClassLoader().loadClass(providerClass).newInstance()); } catch (final Exception e) { diff --git a/jbatch/src/main/java/org/apache/batchee/container/services/persistence/jpa/provider/EEEntityManagerProvider.java b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/jpa/provider/EEEntityManagerProvider.java new file mode 100644 index 0000000..399c099 --- /dev/null +++ b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/jpa/provider/EEEntityManagerProvider.java @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.batchee.container.services.persistence.jpa.provider; + +import org.apache.batchee.container.services.factory.CDIBatchArtifactFactory; +import org.apache.batchee.container.services.persistence.jpa.EntityManagerProvider; + +import javax.persistence.EntityManager; +import java.util.Properties; + +/** + * Designed to use a container entity manager relying on JTA to commit. + * The EntityManager is a CDI bean with the qualifier @Named. + * Default name is "batcheeJpaEm" but it can be customized using "persistence.jpa.ee.entity-manager.name" property. + * + * Note: the bean should be scoped @ApplicationScoped. + * + * Typically: + * + * + + @PersistenceContext + @Produces + @Named + private EntityManager batcheeJpaEm; + + */ +public class EEEntityManagerProvider implements EntityManagerProvider { + private EntityManager instance; + + @Override + public EntityManager newEntityManager() { + return instance; + } + + @Override + public void release(final EntityManager entityManager) { + // no-op + } + + @Override + public void init(final Properties batchConfig) { + final String beanName = batchConfig.getProperty("persistence.jpa.ee.entity-manager.name", "batcheeJpaEm"); + instance = EntityManager.class.cast(new CDIBatchArtifactFactory().load(beanName).getValue()); + } +} diff --git a/jbatch/src/main/java/org/apache/batchee/container/services/persistence/jpa/provider/EETransactionProvider.java b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/jpa/provider/EETransactionProvider.java new file mode 100644 index 0000000..0d7d3c9 --- /dev/null +++ b/jbatch/src/main/java/org/apache/batchee/container/services/persistence/jpa/provider/EETransactionProvider.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.batchee.container.services.persistence.jpa.provider; + +import org.apache.batchee.container.services.persistence.jpa.TransactionProvider; +import org.apache.batchee.container.services.transaction.JTAUserTransactionAdapter; + +import javax.persistence.EntityManager; +import javax.transaction.Transaction; +import java.util.Properties; + +public class EETransactionProvider implements TransactionProvider { + private JTAUserTransactionAdapter jta; + + @Override + public Object start(final EntityManager em) { // ensure internal actions are done in a dedicated tx + return jta.beginSuspending(); + } + + @Override + public void commit(final Object o) { + try { + jta.commit(); + } finally { + if (o != null) { + jta.resume(Transaction.class.cast(o)); + } + } + } + + @Override + public void rollback(final Object tx, final Exception e) { + jta.rollback(); // TODO: check status or not that important? + } + + @Override + public void init(final Properties batchConfig) { + jta = new JTAUserTransactionAdapter(); // reuse the existing logic to get the tx mgr + } +} diff --git a/jbatch/src/main/java/org/apache/batchee/container/services/transaction/JTAUserTransactionAdapter.java b/jbatch/src/main/java/org/apache/batchee/container/services/transaction/JTAUserTransactionAdapter.java index 4a1ac0b..3d6c443 100755 --- a/jbatch/src/main/java/org/apache/batchee/container/services/transaction/JTAUserTransactionAdapter.java +++ b/jbatch/src/main/java/org/apache/batchee/container/services/transaction/JTAUserTransactionAdapter.java @@ -22,9 +22,11 @@ import javax.naming.InitialContext; import javax.transaction.HeuristicMixedException; import javax.transaction.HeuristicRollbackException; +import javax.transaction.InvalidTransactionException; import javax.transaction.NotSupportedException; import javax.transaction.RollbackException; import javax.transaction.SystemException; +import javax.transaction.Transaction; import javax.transaction.TransactionManager; public class JTAUserTransactionAdapter implements TransactionManagerAdapter { @@ -91,6 +93,28 @@ public void begin() throws TransactionManagementException { } } + public Transaction beginSuspending() throws TransactionManagementException { + try { + final Transaction t = mgr.getTransaction() != null ? mgr.suspend() : null; + mgr.begin(); + return t; + } catch (final NotSupportedException e) { + throw new TransactionManagementException(e); + } catch (final SystemException e) { + throw new TransactionManagementException(e); + } + } + + public void resume(final Transaction transaction) { + try { + mgr.resume(transaction); + } catch (final InvalidTransactionException e) { + throw new TransactionManagementException(e); + } catch (final SystemException e) { + throw new TransactionManagementException(e); + } + } + @Override public void commit() throws TransactionManagementException { try {