[
https://issues.apache.org/jira/browse/CAMEL-7269?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14280049#comment-14280049
]
Grzegorz Grzybek edited comment on CAMEL-7269 at 1/16/15 11:03 AM:
-------------------------------------------------------------------
camel-jpa uses spring-orm (for camel 2.12.0 it is spring-orm-3.2.4.RELEASE).
Even if JpaConsumer (and JpaProducer) calls
{{javax.persistence.EntityManager#joinTransaction()}}, the invocation is
intercepted by spring-orm's
{{org.springframework.orm.jpa.ExtendedEntityManagerCreator.ExtendedEntityManagerInvocationHandler#doJoinTransaction()}}
method which delegates only if JTA is in use. So for
{{transaction-type="RESOURCE_LOCAL"}} the call is not delegated.
Here's working example:
h6. META-INF/persistence.xml
{code:xml}
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="camel" transaction-type="RESOURCE_LOCAL">
<class>grgr.test.camel.model.Person</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
{code}
h6. JUnit test
{code:java}
public class JpaTest extends CamelTestSupport {
public static Logger LOG = LoggerFactory.getLogger(JpaTest.class);
public static DateFormat TS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private javax.sql.DataSource ds;
private EntityManagerFactory emf;
@Override
protected CamelContext createCamelContext() throws Exception {
DataSource dataSource = new DataSource();
this.ds = dataSource;
dataSource.setDriverClassName(Driver.class.getName());
// docker PostgreSQL instance
dataSource.setUrl("jdbc:postgresql://172.17.0.2:5432/fuse?ApplicationName=QM");
dataSource.setUsername("postgres");
dataSource.setPassword("fuse");
LocalEntityManagerFactoryBean localEntityManagerFactoryBean = new
LocalEntityManagerFactoryBean();
localEntityManagerFactoryBean.setJpaDialect(new OpenJpaDialect());
localEntityManagerFactoryBean.setPersistenceUnitName("camel");
HashMap<String, Object> jpaProperties = new HashMap<>();
jpaProperties.put("openjpa.ConnectionFactory", this.ds);
localEntityManagerFactoryBean.setJpaPropertyMap(jpaProperties);
localEntityManagerFactoryBean.afterPropertiesSet();
this.emf = localEntityManagerFactoryBean.getObject();
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setDataSource(this.ds);
txManager.setEntityManagerFactory(this.emf);
txManager.afterPropertiesSet();
DefaultCamelContext context = (DefaultCamelContext)
super.createCamelContext();
SimpleRegistry registry = new SimpleRegistry();
registry.put("txManager", txManager);
context.setRegistry(registry);
JpaComponent jpaComponent = new JpaComponent();
jpaComponent.setEntityManagerFactory(this.emf);
jpaComponent.setTransactionManager(txManager);
context.addComponent("jpa", jpaComponent);
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start")
.log("Body written: ${body}")
.to("jpa:grgr.test.camel.model.Person");
from("jpa:grgr.test.camel.model.Person?consumeDelete=false&consumer.delay=5000")
.transacted()
.log("Body read: ${body}")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws
Exception {
Person person =
exchange.getIn().getBody(Person.class);
LOG.info("Received: {} ({})", person.getName(),
person.getDate());
}
});
}
});
return context;
}
@Test
public void testJpaWrite() throws Exception {
Person result = template.requestBody("direct:start", new
Person("Terrence", new Date()), Person.class);
LOG.info("Result: {}: {}", result.getId(), result.getName());
}
}
{code}
Please reopen if the problem persists.
was (Author: gzres):
camel-jpa uses spring-orm (for camel 2.12.0 it is spring-orm-3.2.4.RELEASE).
Even if JpaConsumer (and JpaProducer) calls
{{javax.persistence.EntityManager#joinTransaction()}}, the invocation is
intercepted by spring-orm's
{{org.springframework.orm.jpa.ExtendedEntityManagerCreator.ExtendedEntityManagerInvocationHandler#doJoinTransaction()}}
method which delegates only if JTA is in use. So for
{{transaction-type="RESOURCE_LOCAL"}} the call is not delegated.
Here's working example:
h6. META-INF/persistence.xml
{code:xml}
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<persistence-unit name="camel" transaction-type="RESOURCE_LOCAL">
<class>grgr.test.camel.model.Person</class>
<exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>
</persistence>
{code}
h6. JUnit test
{code:java}
public class JpaTest extends CamelTestSupport {
public static Logger LOG = LoggerFactory.getLogger(JpaTest.class);
public static DateFormat TS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private javax.sql.DataSource ds;
private EntityManagerFactory emf;
@Override
protected CamelContext createCamelContext() throws Exception {
DataSource dataSource = new DataSource();
this.ds = dataSource;
dataSource.setDriverClassName(Driver.class.getName());
// docker PostgreSQL instance
dataSource.setUrl("jdbc:postgresql://172.17.0.2:5432/fuse?ApplicationName=QM");
dataSource.setUsername("postgres");
dataSource.setPassword("fuse");
LocalEntityManagerFactoryBean localEntityManagerFactoryBean = new
LocalEntityManagerFactoryBean();
localEntityManagerFactoryBean.setJpaDialect(new OpenJpaDialect());
localEntityManagerFactoryBean.setPersistenceUnitName("camel");
HashMap<String, Object> jpaProperties = new HashMap<>();
jpaProperties.put("openjpa.ConnectionFactory", this.ds);
localEntityManagerFactoryBean.setJpaPropertyMap(jpaProperties);
localEntityManagerFactoryBean.afterPropertiesSet();
this.emf = localEntityManagerFactoryBean.getObject();
JpaTransactionManager txManager = new JpaTransactionManager();
txManager.setDataSource(this.ds);
txManager.setEntityManagerFactory(this.emf);
txManager.afterPropertiesSet();
DefaultCamelContext context = (DefaultCamelContext)
super.createCamelContext();
SimpleRegistry registry = new SimpleRegistry();
registry.put("txManager", txManager);
context.setRegistry(registry);
JpaComponent jpaComponent = new JpaComponent();
jpaComponent.setEntityManagerFactory(this.emf);
jpaComponent.setTransactionManager(txManager);
context.addComponent("jpa", jpaComponent);
context.addRoutes(new RouteBuilder() {
@Override
public void configure() throws Exception {
from("direct:start")
.transacted()
.log("Body written: ${body}")
.to("jpa:Person");
from("jpa:grgr.test.camel.model.Person?consumeDelete=false&consumer.delay=5000")
.transacted()
.log("Body read: ${body}")
.process(new Processor() {
@Override
public void process(Exchange exchange) throws
Exception {
Person person =
exchange.getIn().getBody(Person.class);
LOG.info("Received: {} ({})", person.getName(),
person.getDate());
}
});
}
});
return context;
}
@Test
public void testJpaWrite() throws Exception {
Person result = template.requestBody("direct:start", new
Person("Terrence", new Date()), Person.class);
LOG.info("Result: {}: {}", result.getId(), result.getName());
}
}
{code}
Please reopen if the problem persists.
> camel-jpa - joinTransaction called for RESOURCE_LOCAL datasource
> ----------------------------------------------------------------
>
> Key: CAMEL-7269
> URL: https://issues.apache.org/jira/browse/CAMEL-7269
> Project: Camel
> Issue Type: Bug
> Components: camel-jpa
> Affects Versions: 2.12.0
> Environment: tomcat+eclipselink+camel 2.12.2
> Reporter: Hristo Sabev
> Assignee: Grzegorz Grzybek
> Fix For: Future
>
>
> At line 82, JpaConsumer calls entityManager.joinTransaction(). This call
> cannot really work in environmnent without JTA. This is a change since 2.11.x
> and earlier versions where non JTA environments were supported
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)