camel-issues mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Grzegorz Grzybek (JIRA)" <j...@apache.org>
Subject [jira] [Comment Edited] (CAMEL-7269) camel-jpa - joinTransaction called for RESOURCE_LOCAL datasource
Date Fri, 16 Jan 2015 11:03:35 GMT

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

Mime
View raw message