Repository: camel Updated Branches: refs/heads/camel-2.15.x 1f499f626 -> 22b555852 refs/heads/master 26eceeec1 -> 1af80c07b
CAMEL-9177: jpa producer should be more robust if the EM is closed. Thanks to Pascal S for the suggestion. Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/1af80c07 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/1af80c07 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/1af80c07 Branch: refs/heads/master Commit: 1af80c07b38515d1b75cbd6ee762bb9a3281bc1f Parents: 26eceee Author: Claus Ibsen <davscl...@apache.org> Authored: Tue Sep 29 08:14:02 2015 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Tue Sep 29 08:14:02 2015 +0200 ---------------------------------------------------------------------- .../jpa/JpaCloseEntityManagerOnCompletion.java | 8 ++- .../apache/camel/component/jpa/JpaHelper.java | 12 +++- .../apache/camel/component/jpa/JpaProducer.java | 2 +- .../idempotent/jpa/JpaMessageIdRepository.java | 8 +-- .../camel/processor/jpa/JpaWireTapTest.java | 76 ++++++++++++++++++++ 5 files changed, 99 insertions(+), 7 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/1af80c07/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaCloseEntityManagerOnCompletion.java ---------------------------------------------------------------------- diff --git a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaCloseEntityManagerOnCompletion.java b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaCloseEntityManagerOnCompletion.java index c508eca..b0e41ba 100644 --- a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaCloseEntityManagerOnCompletion.java +++ b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaCloseEntityManagerOnCompletion.java @@ -32,7 +32,13 @@ public class JpaCloseEntityManagerOnCompletion extends SynchronizationAdapter { @Override public void onDone(Exchange exchange) { - entityManager.close(); + try { + if (entityManager.isOpen()) { + entityManager.close(); + } + } catch (Exception e) { + // ignore + } } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/1af80c07/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaHelper.java ---------------------------------------------------------------------- diff --git a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaHelper.java b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaHelper.java index 44a5913..50d5c22 100644 --- a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaHelper.java +++ b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaHelper.java @@ -41,7 +41,7 @@ public final class JpaHelper { * @return the entity manager (is never null) */ public static EntityManager getTargetEntityManager(Exchange exchange, EntityManagerFactory entityManagerFactory, - boolean usePassedInEntityManager, boolean useSharedEntityManager) { + boolean usePassedInEntityManager, boolean useSharedEntityManager, boolean allowRecreate) { EntityManager em = null; // favor using entity manager provided as a header from the end user @@ -68,6 +68,16 @@ public final class JpaHelper { } } + if (allowRecreate && em == null || !em.isOpen()) { + // create a new entity manager + em = entityManagerFactory.createEntityManager(); + if (exchange != null) { + // we want to reuse the EM so store as property and make sure we close it when done with the exchange + exchange.setProperty(JpaConstants.ENTITY_MANAGER, em); + exchange.addOnCompletion(new JpaCloseEntityManagerOnCompletion(em)); + } + } + return em; } http://git-wip-us.apache.org/repos/asf/camel/blob/1af80c07/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaProducer.java b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaProducer.java index 72532b6..dc73588 100644 --- a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaProducer.java +++ b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaProducer.java @@ -55,7 +55,7 @@ public class JpaProducer extends DefaultProducer { public void process(final Exchange exchange) { // resolve the entity manager before evaluating the expression final EntityManager entityManager = getTargetEntityManager(exchange, entityManagerFactory, - getEndpoint().isUsePassedInEntityManager(), getEndpoint().isSharedEntityManager()); + getEndpoint().isUsePassedInEntityManager(), getEndpoint().isSharedEntityManager(), true); final Object values = expression.evaluate(exchange, Object.class); if (values != null) { http://git-wip-us.apache.org/repos/asf/camel/blob/1af80c07/components/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java ---------------------------------------------------------------------- diff --git a/components/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java b/components/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java index b488277..f992715 100644 --- a/components/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java +++ b/components/camel-jpa/src/main/java/org/apache/camel/processor/idempotent/jpa/JpaMessageIdRepository.java @@ -87,7 +87,7 @@ public class JpaMessageIdRepository extends ServiceSupport implements ExchangeId @Override public boolean add(final Exchange exchange, final String messageId) { - final EntityManager entityManager = getTargetEntityManager(exchange, entityManagerFactory, true, sharedEntityManager); + final EntityManager entityManager = getTargetEntityManager(exchange, entityManagerFactory, true, sharedEntityManager, true); // Run this in single transaction. Boolean rc = transactionTemplate.execute(new TransactionCallback<Boolean>() { @@ -122,7 +122,7 @@ public class JpaMessageIdRepository extends ServiceSupport implements ExchangeId @Override public boolean contains(final Exchange exchange, final String messageId) { - final EntityManager entityManager = getTargetEntityManager(exchange, entityManagerFactory, true, sharedEntityManager); + final EntityManager entityManager = getTargetEntityManager(exchange, entityManagerFactory, true, sharedEntityManager, true); // Run this in single transaction. Boolean rc = transactionTemplate.execute(new TransactionCallback<Boolean>() { @@ -151,7 +151,7 @@ public class JpaMessageIdRepository extends ServiceSupport implements ExchangeId @Override public boolean remove(final Exchange exchange, final String messageId) { - final EntityManager entityManager = getTargetEntityManager(exchange, entityManagerFactory, true, sharedEntityManager); + final EntityManager entityManager = getTargetEntityManager(exchange, entityManagerFactory, true, sharedEntityManager, true); Boolean rc = transactionTemplate.execute(new TransactionCallback<Boolean>() { public Boolean doInTransaction(TransactionStatus status) { @@ -188,7 +188,7 @@ public class JpaMessageIdRepository extends ServiceSupport implements ExchangeId @ManagedOperation(description = "Clear the store") public void clear() { - final EntityManager entityManager = getTargetEntityManager(null, entityManagerFactory, true, sharedEntityManager); + final EntityManager entityManager = getTargetEntityManager(null, entityManagerFactory, true, sharedEntityManager, true); Boolean rc = transactionTemplate.execute(new TransactionCallback<Boolean>() { public Boolean doInTransaction(TransactionStatus status) { http://git-wip-us.apache.org/repos/asf/camel/blob/1af80c07/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaWireTapTest.java ---------------------------------------------------------------------- diff --git a/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaWireTapTest.java b/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaWireTapTest.java new file mode 100644 index 0000000..da32a98 --- /dev/null +++ b/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaWireTapTest.java @@ -0,0 +1,76 @@ +/** + * 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.camel.processor.jpa; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.jpa.JpaComponent; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.examples.SendEmail; +import org.apache.camel.spring.SpringRouteBuilder; +import org.junit.Test; + +/** + * @version + */ +public class JpaWireTapTest extends AbstractJpaTest { + protected static final String SELECT_ALL_STRING = "select x from " + SendEmail.class.getName() + " x"; + + @Test + public void testRouteJpa() throws Exception { + // should auto setup transaction manager and entity factory + JpaComponent jpa = context.getComponent("jpa", JpaComponent.class); + assertNotNull("Should have been auto assigned", jpa.getEntityManagerFactory()); + assertNotNull("Should have been auto assigned", jpa.getTransactionManager()); + + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMessageCount(2); + + template.sendBody("direct:start", new SendEmail("some...@somewhere.org")); + + assertMockEndpointsSatisfied(); + assertEntityInDB(2); + } + + @Override + protected RouteBuilder createRouteBuilder() { + return new SpringRouteBuilder() { + public void configure() { + + from("direct:start") + .to("jpa://" + SendEmail.class.getName()) + .wireTap("direct:tap") + .to("mock:result"); + + from("direct:tap") + .delay(constant("1000")) + .setBody(constant(new SendEmail("m...@you.org"))) + .to("jpa://" + SendEmail.class.getName()) + .to("mock:result"); + } + }; + } + + @Override + protected String routeXml() { + return "org/apache/camel/processor/jpa/springJpaRouteTest.xml"; + } + + @Override + protected String selectAllString() { + return SELECT_ALL_STRING; + } +} \ No newline at end of file