[ 
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:04 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/camel");
        dataSource.setUsername("postgres");
        dataSource.setPassword("postgres");

        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")
                        .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.

> 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)

Reply via email to