LibraryToggle FramesPrintFeedback

You can store a Java entity bean in a database by sending it to a JPA producer endpoint. The body of the In message is assumed to be an entity bean (that is, a POJO with an @Entity annotation on it) or a collection or an array of entity beans.

If the body does not contain one of the preceding types, put a Message TranslatorMessage Translator in front of the endpoint to perform the necessary conversion first.

jpa:[entityClassName][?options]

For sending to the endpoint, the entityClassName is optional. If specified, it helps the Type Converter to ensure the body is of the correct type.

For consuming, the entityClassName is mandatory.

You can append query options to the URI in the following format, ?option=value&option=value&...

Name Default Value Description
entityType entityClassName Overrides the entityClassName from the URI.
persistenceUnit camel The JPA persistence unit used by default.
consumeDelete true JPA consumer only: If true, the entity is deleted after it is consumed; if false, the entity is not deleted.
consumeLockEntity true JPA consumer only: Specifies whether or not to set an exclusive lock on each entity bean while processing the results from polling.
flushOnSend true JPA producer only: Flushes the EntityManager after the entity bean has been persisted.
maximumResults -1 JPA consumer only: Set the maximum number of results to retrieve on the Query.
transactionManager null Fuse Mediation Router 1.6.1/2.0: Specifies the transaction manager to use. If none provided, Fuse Mediation Router will use a JpaTransactionManager by default. Can be used to set a JTA transaction manager (for integration with an EJB container).
consumer.delay 500 JPA consumer only: Delay in milliseconds between each poll.
consumer.initialDelay 1000 JPA consumer only: Milliseconds before polling starts.
consumer.useFixedDelay false JPA consumer only: Set to true to use fixed delay between polls, otherwise fixed rate is used. See ScheduledExecutorService in JDK for details.
maxMessagesPerPoll 0 Fuse Mediation Router 2.0:JPA consumer only: An integer value to define the maximum number of messages to gather per poll. By default, no maximum is set. Can be used to avoid polling many thousands of messages when starting up the server. Set a value of 0 or negative to disable.
consumer.query JPA consumer only: To use a custom query when consuming data.
consumer.namedQuery JPA consumer only: To use a named query when consuming data.
consumer.nativeQuery JPA consumer only: To use a custom native query when consuming data.
consumer.resultClass Camel 2.7: JPA consumer only: Defines the type of the returned payload (we will call entityManager.createNativeQuery(nativeQuery, resultClass) instead of entityManager.createNativeQuery(nativeQuery)). Without this option, we will return an object array. Only has an affect when using in conjunction with native query when consuming data.
usePersist false Camel 2.5: JPA producer only: Indicates to use entityManager.persist(entity) instead of entityManager.merge(entity). Note: entityManager.persist(entity) doesn't work for detached entities (where the EntityManager has to execute an UPDATE instead of an INSERT query)!

Fuse Mediation Router adds the following message headers to the exchange:

Header Type Description
CamelJpaTemplate JpaTemplate Fuse Mediation Router 2.0: The JpaTemplate object that is used to access the entity bean. You need this object in some situations, for instance in a type converter or when you are doing some custom processing.

In this section we will use the JPA based idempotent repository.

First we need to setup a persistence-unit in the persistence.xml file:

<persistence-unit name="idempotentDb" transaction-type="RESOURCE_LOCAL">
   <class>org.apache.camel.processor.idempotent.jpa.MessageProcessed</class>
 
   <properties>
     <property name="openjpa.ConnectionURL" value="jdbc:derby:target/idempotentTest;create=true"/>
     <property name="openjpa.ConnectionDriverName" value="org.apache.derby.jdbc.EmbeddedDriver"/>
     <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema"/>
     <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO"/>
   </properties>
 </persistence-unit>

Second we have to setup a org.springframework.orm.jpa.JpaTemplate which is used by the org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository:

<!-- this is standard spring JPA configuration -->
 <bean id="jpaTemplate" class="org.springframework.orm.jpa.JpaTemplate">
     <property name="entityManagerFactory" ref="entityManagerFactory"/>
 </bean>
 
 <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
     <!-- we use idempotentDB as the persitence unit name defined in the persistence.xml file -->
     <property name="persistenceUnitName" value="idempotentDb"/>
 </bean>

Afterwards we can configure our org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository:

<!-- we define our jpa based idempotent repository we want to use in the file consumer -->
 <bean id="jpaStore" class="org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository">
     <!-- Here we refer to the spring jpaTemplate -->
     <constructor-arg index="0" ref="jpaTemplate"/>
     <!-- This 2nd parameter is the name  (= a cateogry name).
          You can have different repositories with different names -->
     <constructor-arg index="1" value="FileConsumer"/>
 </bean>

And finally we can create our JPA idempotent repository in the spring XML file as well:

 <camel:camelContext>	
     <camel:route id="JpaMessageIdRepositoryTest">
         <camel:from uri="direct:start" />
         <camel:idempotentConsumer messageIdRepositoryRef="jpaStore">
             <camel:header>messageId</camel:header>
             <camel:to uri="mock:result" />
         </camel:idempotentConsumer>
     </camel:route>
 </camel:camelContext>
Comments powered by Disqus