camel-jpa
Since Camel 1.0
Both producer and consumer are supported
JPA 组件使您能够使用 EJB 3 的 Java Persistence Architecture (JPA) 从持久存储中存储和检索 Java 对象,JPA 是一个标准接口层,它包装了对象/关系映射 (ORM) 产品,例如 OpenJPA、Hibernate、TopLink 等在。
Maven 用户需要pom.xml
为此组件添加以下依赖项:
<dependency> <groupId>org.apache.camel</groupId> <artifactId>camel-jpa</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>
您可以通过将 Java 实体 bean 发送到 JPA 生产者端点来将其存储在数据库中。In消息的主体被假定为实体 bean(即带有
如果主体是实体列表,请确保使用entityType=java.util.List作为传递给生产者端点的配置。
如果正文不包含前面列出的类型之一,请在端点前面放置一个消息转换器以首先执行必要的转换。
您也可以将query
,namedQuery
或nativeQuery
用于生产者。同样在parameters
值中,您可以使用简单表达式,它允许您从消息正文、标题等中检索参数值。这些查询可用于使用SELECT
JPQL/SQL 语句检索一组数据以及执行批量 update/delete 与 using UPDATE
/ DELETE
JPQL/SQL 语句。请注意,如果您用 namedQuery
执行UPDATE
/DELETE
需要指定 useExecuteUpdate
为true,与 query
和 nativeQuery
不同,不要查看命名查询。
从端点消费
使用来自 JPA 使用者端点的消息会删除(或更新)数据库中的实体 bean。这允许您将数据库表用作逻辑队列:消费者从队列中获取消息,然后删除/更新它们以在逻辑上将它们从队列中删除。
如果您不想在处理完实体 bean 时(以及完成路由时)删除实体 bean,您可以用consumeDelete=false
在 URI 上指定。这将导致在每次轮询中处理实体。
如果您更愿意对实体执行一些更新以将其标记为已处理(例如将其从未来的查询中排除),那么您可以使用
您可以使用
如果您消耗大量 (100K+) 行并遇到 OutOfMemory 问题,您应该将 maximumResults 设置为合理的值。
URI格式
jpa:entityClassName[?options]
为了发送到端点,entityClassName是可选的。如果指定,它有助于
对于消费,entityClassName是强制性的。
配置选项
Camel 组件在两个单独的级别上配置:
-
component level
-
endpoint level
配置组件选项
组件级别是最高级别,包含端点继承的通用和通用配置。例如,组件可能具有安全设置、身份验证凭据、网络连接 url 等。
一些组件只有几个选项,而其他组件可能有很多。由于组件通常具有常用的预配置默认值,因此您可能通常只需要在组件上配置几个选项;或者根本没有。
可以使用
配置端点选项
您发现自己配置最多的地方是在端点上,因为端点通常有很多选项,这允许您配置需要端点执行的操作。这些选项还分为端点是用作消费者(from)还是用作生产者(to),或两者都使用。
配置端点通常直接在端点 URI 中作为路径和查询参数完成。您还可以使用
配置选项时的一个好习惯是使用
以下两部分列出了所有选项,首先是组件,然后是端点。
组件选项
JPA 组件支持 7 个选项,如下所列。
姓名 | 描述 | 默认 | 类型 |
---|---|---|---|
entityManagerFactory(通用) | 使用 EntityManagerFactory。强烈建议这样配置。 | EntityManagerFactory实体管理器工厂 | |
joinTransaction(普通) | camel-jpa 组件默认会加入事务。您可以使用此选项将其关闭,例如,如果您使用 LOCAL_RESOURCE 并且连接事务不适用于您的 JPA 提供程序。此选项也可以在 JpaComponent 上全局设置,而不必在所有端点上设置。 | 真的 | boolean |
sharedEntityManager(通用) | 是否为消费者/生产者使用 Spring 的 SharedEntityManager。请注意,在大多数情况下,joinTransaction 应设置为 false,因为这不是 EXTENDED EntityManager。 | boolean | |
transactionManager (common) | 使用 PlatformTransactionManager 来管理事务。 | PlatformTransactionManager | |
bridgeErrorHandler(消费者) | 允许将消费者桥接到 Camel 路由错误处理程序,这意味着在消费者尝试获取传入消息或类似消息时发生的任何异常现在都将作为消息处理并由路由错误处理程序处理。默认情况下,消费者将使用 org.apache.camel.spi.ExceptionHandler 来处理异常,这些异常将被记录在 WARN 或 ERROR 级别并被忽略。 | boolean | |
lazyStartProducer(生产者) | 生产者是否应该懒惰地启动(在第一条消息上)。通过延迟启动,您可以使用它来允许 CamelContext 和路由在生产者可能在启动过程中失败并导致路由启动失败的情况下启动。通过延迟这个启动是惰性的,启动失败可以在通过 Camel 的路由错误处理程序路由消息期间处理。请注意,当处理第一条消息时,创建和启动生产者可能需要一些时间并延长处理的总处理时间。 | boolean | |
autowiredEnabled(高级) | 是否启用自动装配。这用于自动自动装配选项(该选项必须标记为自动装配),通过在注册表中查找是否存在匹配类型的单个实例,然后在组件上进行配置。这可用于自动配置 JDBC 数据源、JMS 连接工厂、AWS 客户端等。 | 真的 | boolean |
端点选项
JPA 端点是使用 URI 语法配置的:
jpa:entityType
具有以下路径和查询参数:
路径参数(1个参数)
名称 | 描述 | 默认 | 类型 |
---|---|---|---|
entityType (common) | 必需的实体类名称。 | Class |
查询参数(44 个参数)
姓名 | 描述 | 默认 | 类型 |
---|---|---|---|
joinTransaction(普通) | camel-jpa 组件默认会加入事务。您可以使用此选项将其关闭,例如,如果您使用 LOCAL_RESOURCE 并且连接事务不适用于您的 JPA 提供程序。此选项也可以在 JpaComponent 上全局设置,而不必在所有端点上设置。 | 真的 | boolean |
maximumResults (common) | 设置要在查询上检索的最大结果数。 | -1 | int |
namedQuery (common) | 使用命名查询。 | String | |
nativeQuery(常见) | 使用自定义本机查询。在使用本机查询时,您可能还想使用选项 resultClass。 | String | |
persistenceUnit (common) | 必需默认情况下使用的 JPA 持久性单元。 | camel | String |
query (common) | 使用自定义查询。 | String | |
resultClass (common) | 定义返回负载的类型(我们将调用 entityManager.createNativeQuery(nativeQuery, resultClass) 而不是 entityManager.createNativeQuery(nativeQuery))。如果没有这个选项,我们将返回一个对象数组。仅在使用数据时与本机查询结合使用时才有影响。 | Class | |
bridgeErrorHandler(消费者) | 允许将消费者桥接到 Camel 路由错误处理程序,这意味着在消费者尝试获取传入消息或类似消息时发生的任何异常现在都将作为消息处理并由路由错误处理程序处理。默认情况下,消费者将使用 org.apache.camel.spi.ExceptionHandler 来处理异常,这些异常将被记录在 WARN 或 ERROR 级别并被忽略。 | boolean | |
consumeDelete (consumer) | 如果为true,实体被消费后被删除;如果为 false,则不会删除该实体。 | true | boolean |
consumeLockEntity (consumer) | 指定在处理轮询结果时是否对每个实体 bean 设置排他锁。 | true | boolean |
deleteHandler(消费者) | 在消费者完成交换处理后使用自定义 DeleteHandler 删除行。 | DeleteHandler | |
lockModeType(消费者) | 在消费者上配置锁定模式。枚举值:读写乐观的OPTIMISTIC_FORCE_INCREMENT悲观阅读悲观写悲观_FORCE_INCREMENT没有任何 | PESSIMISTIC_WRITE | LockModeType |
maxMessagesPerPoll(消费者) | 一个整数值,用于定义每次轮询收集的最大消息数。默认情况下,没有设置最大值。可用于避免在启动服务器时轮询数千条消息。将值设置为 0 或负值以禁用。 | int | |
preDeleteHandler(消费者) | 在消费者读取实体后使用自定义 Pre-DeleteHandler 删除行。 | DeleteHandler | |
sendEmptyMessageWhenIdle(消费者) | 如果轮询使用者没有轮询任何文件,您可以启用此选项以发送空消息(无正文)。 | boolean | |
skipLockedEntity(消费者) | 配置是否在锁定时使用 NOWAIT 并静默跳过实体。 | boolean | |
transacted (consumer) | 是否在事务处理模式下运行使用者,当整个批处理完成后,所有消息将提交或回滚。默认行为 (false) 是提交所有先前成功处理的消息,并且仅回滚最后失败的消息。 | boolean | |
exceptionHandler (consumer (advanced)) | 让消费者使用自定义的 ExceptionHandler。请注意,如果选项 bridgeErrorHandler 已启用,则此选项未在使用中。默认情况下,消费者将处理异常,这些异常将记录在 WARN 或 ERROR 级别并被忽略。 | ExceptionHandler | |
exchangePattern(消费者(高级)) | 当消费者创建交换时设置交换模式。枚举值:InOnly,InOut,InOptionalOut | ExchangePattern | |
parameters (consumer (advanced)) | 此键/值映射用于构建查询参数。它应该是泛型类型 java.util.Map,其中键是给定 JPA 查询的命名参数,值是您要为其选择的相应有效值。用于生产者时,可以使用简单表达式作为参数值。它允许您从消息正文、标题等中检索参数值。 | Map | |
pollStrategy(消费者(高级)) | 一个可插入的 org.apache.camel.PollingConsumerPollingStrategy 允许您提供自定义实现来控制在创建 Exchange 并在 Camel 中路由之前轮询操作期间通常发生的错误处理。 | PollingConsumerPollStrategy | |
findEntity(生产者) | 如果启用,那么生产者将使用消息正文作为键和 entityType 作为类型来查找单个实体类。这可以用来代替查询来查找单个实体。 | boolean | |
flushOnSend(生产者) | 在实体 bean 被持久化后刷新 EntityManager。 | true | boolean |
lazyStartProducer(生产者) | 生产者是否应该懒惰地启动(在第一条消息上)。通过延迟启动,您可以使用它来允许 CamelContext 和路由在生产者可能在启动过程中失败并导致路由启动失败的情况下启动。通过延迟这个启动是惰性的,启动失败可以在通过 Camel 的路由错误处理程序路由消息期间处理。请注意,当处理第一条消息时,创建和启动生产者可能需要一些时间并延长处理的总处理时间。 | boolean | |
remove (producer) | 表示使用 entityManager.remove(entity)。 | boolean | |
useExecuteUpdate(生产者) | 配置生产者执行查询时是否使用executeUpdate()。当您使用 INSERT、UPDATE 或 DELETE 语句作为命名查询时,您需要将此选项指定为 'true'。 | boolean | |
usePersist(生产者) | 表示使用 entityManager.persist(entity) 而不是 entityManager.merge(entity)。注意:entityManager.persist(entity) 不适用于分离的实体(其中 EntityManager 必须执行 UPDATE 而不是 INSERT 查询)!。 | boolean | |
usePassedInEntityManager(生产者(高级)) | 如果设置为 true,则 Camel 将使用头文件 JpaConstants.ENTITY_MANAGER 中的 EntityManager 而不是组件/端点上配置的实体管理器。这允许最终用户控制将使用哪个实体管理器。 | boolean | |
entityManagerProperties(高级) | 实体管理器使用的附加属性。 | map | |
sharedEntityManager(高级) | 是否为消费者/生产者使用 Spring 的 SharedEntityManager。请注意,在大多数情况下,joinTransaction 应设置为 false,因为这不是 EXTENDED EntityManager。 | boolean | |
backoffErrorThreshold(调度程序) | 在 backoffMultipler 启动之前应该发生的后续错误轮询(由于某些错误而失败)的数量。 | int | |
backoffIdleThreshold(调度程序) | 在 backoffMultipler 应该启动之前应该发生的后续空闲轮询的数量。 | int | |
backoffMultiplier(调度程序) | 如果连续出现许多后续空闲/错误,则让计划的轮询使用者退避。乘数是在下一次实际尝试再次发生之前将被跳过的轮询次数。使用此选项时,还必须配置 backoffIdleThreshold 和/或 backoffErrorThreshold。 | int | |
delay (scheduler) | 下一次轮询前的毫秒数。 | 500 | long |
greedy (scheduler) | 如果启用了贪婪,则 ScheduledPollConsumer 将立即再次运行,如果前一次运行轮询了 1 条或多条消息。 | boolean | |
initialDelay (scheduler) | 第一次轮询开始前的毫秒数。 | 1000 | long |
repeatCount (scheduler) | 指定火灾次数的最大限制。因此,如果将其设置为 1,调度程序将只触发一次。如果将其设置为 5,则它只会触发 5 次。零或负值意味着永远燃烧。 | long | |
runLoggingLevel(调度程序) | 消费者在轮询时记录开始/完成日志行。此选项允许您为此配置日志记录级别。枚举值:痕迹调试信息警告错误离开 | TRACE | LoggingLevel |
ScheduledExecutorService(调度程序) | 允许配置自定义/共享线程池以供使用者使用。默认情况下,每个使用者都有自己的单线程线程池。 | ScheduledExecutorServiceScheduledExecutorService | |
scheduler (scheduler) | 使用来自camel-spring 或camel-quartz 组件的cron 调度程序。对内置调度器使用值弹簧或石英。 | none | Object |
schedulerProperties(调度程序) | 在使用自定义调度程序或任何基于 Quartz、Spring 的调度程序时配置其他属性。 | map | |
startScheduler(调度程序) | 调度程序是否应该自动启动。 | true | boolean |
timeUnit (scheduler) | initialDelay 和延迟选项的时间单位。枚举值:纳秒微秒毫秒秒分钟小时天 | MILLISECONDS | TimeUnit |
useFixedDelay(调度程序) | 控制是否使用固定延迟或固定速率。有关详细信息,请参阅 JDK 中的 ScheduledExecutorService。 | true | boolean |
消息头
Camel 将以下消息头添加到交换中:
标题 | 类型 | 描述 |
---|---|---|
CamelEntityManager |
EntityManager |
或EntityManager 正在使用的 JPA对象。JpaConsumer``JpaProducer |
CamelJpaParameters |
Map<String, Object> |
将查询参数作为 Exchange 标头传递的替代方法。 |
配置 ENTITYMANAGERFACTORY
强烈建议配置 JPA 组件以使用特定EntityManagerFactory
实例。如果不这样做,每个人JpaEndpoint
都会自动创建自己的实例,EntityManagerFactory
而这些实例通常不是您想要的。
例如,您可以实例化一个引用myEMFactory
实体管理器工厂的 JPA 组件,如下所示:
<bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent"> <property name="entityManagerFactory" ref="myEMFactory"/> </bean>
在JpaComponent
查找自动EntityManagerFactory
从,这意味着你不需要在配置此注册表JpaComponent
如上图所示。只有在有歧义时才需要这样做,在这种情况下,Camel 会记录一个 WARN。
配置事务管理器
该JpaComponent
自动查找TransactionManager
从注册表。如果 Camel 找不到任何TransactionManager
已注册的实例,它也会查找TransactionTemplate
并尝试从中提取TransactionManager
。
如果TransactionTemplate
注册表中没有可用的,JpaEndpoint
将自动创建自己的实例,TransactionManager
其中最常见的不是您想要的。
如果找到多个 的实例TransactionManager
,Camel 将记录一个 WARN。在这种情况下,您可能希望实例化并显式配置引用myTransactionManager
事务管理器的 JPA 组件,如下所示:
<bean id="jpa" class="org.apache.camel.component.jpa.JpaComponent"> <property name="entityManagerFactory" ref="myEMFactory"/> <property name="transactionManager" ref="myTransactionManager"/> </bean>
使用带有命名查询的消费者
对于仅使用选定实体,您可以使用namedQuery
URI 查询选项。首先,您必须在 JPA 实体类中定义命名查询:
@Entity @NamedQuery(name = "step1", query = "select x from MultiSteps x where x.step = 1") public class MultiSteps { ... }
之后,您可以像这样定义一个消费者 uri:
from("jpa://org.apache.camel.examples.MultiSteps?namedQuery=step1")
.to("bean:myBusinessLogic");
使用消费者进行查询
对于仅使用选定实体,您可以使用query
URI 查询选项。您只需要定义查询选项:
from("jpa://org.apache.camel.examples.MultiSteps?query=select o from org.apache.camel.examples.MultiSteps o where o.step = 1")
.to("bean:myBusinessLogic");
使用带有本机查询的使用者
对于仅使用选定实体,您可以使用nativeQuery
URI 查询选项。您只需要定义本机查询选项:
from("jpa://org.apache.camel.examples.MultiSteps?nativeQuery=select * from MultiSteps where step = 1")
.to("bean:myBusinessLogic");
如果您使用本机查询选项,您将在消息正文中收到一个对象数组。
使用带有命名查询的生产者
要检索选定的实体或执行批量更新/删除,您可以使用namedQuery
URI 查询选项。首先,您必须在 JPA 实体类中定义命名查询:
@Entity @NamedQuery(name = "step1", query = "select x from MultiSteps x where x.step = 1") public class MultiSteps { ... }
之后,您可以像这样定义一个生产者 uri:
from("direct:namedQuery")
.to("jpa://org.apache.camel.examples.MultiSteps?namedQuery=step1");
请注意,您需要指定useExecuteUpdate
选项以true
将UPDATE
/DELETE
语句作为命名查询执行。
使用带有查询的生产者
要检索选定的实体或执行批量更新/删除,您可以使用query
URI 查询选项。您只需要定义查询选项:
from("direct:query")
.to("jpa://org.apache.camel.examples.MultiSteps?query=select o from org.apache.camel.examples.MultiSteps o where o.step = 1");
使用带有本机查询的生产者
要检索选定的实体或执行批量更新/删除,您可以使用nativeQuery
URI 查询选项。您只需要定义本机查询选项:
from("direct:nativeQuery")
.to("jpa://org.apache.camel.examples.MultiSteps?resultClass=org.apache.camel.examples.MultiSteps&nativeQuery=select * from MultiSteps where step = 1");
如果您使用本机查询选项而不指定resultClass
,您将在消息正文中收到一个对象数组。
使用基于 JPA 的幂等存储库
使用基于 JPA 的幂等存储库。
程序
-
persistence-unit
在persistence.xml文件中设置一个: -
设置一个
org.springframework.orm.jpa.JpaTemplate
由以下使用的org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository
: -
配置错误格式宏:snippet: java.lang.IndexOutOfBoundsException: Index: 20, Size: 20
-
配置幂等存储库
org.apache.camel.processor.idempotent.jpa.JpaMessageIdRepository
: -
在 Spring XML 文件中创建 JPA 幂等存储库:
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route id="JpaMessageIdRepositoryTest"> <from uri="direct:start" /> <idempotentConsumer messageIdRepositoryRef="jpaStore"> <header>messageId</header> <to uri="mock:result" /> </idempotentConsumer> </route> </camelContext>
在 IDE 中运行此 Camel 组件测试时
如果您直接在 IDE 中运行
org.springframework.transaction.CannotCreateTransactionException: Could not open JPA EntityManager for transaction; nested exception is <openjpa-2.2.1-r422266:1396819 nonfatal user error> org.apache.openjpa.persistence.ArgumentException: This configuration disallows runtime optimization, but the following listed types were not enhanced at build time or at class load time with a javaagent: "org.apache.camel.examples.SendEmail". at org.springframework.orm.jpa.JpaTransactionManager.doBegin(JpaTransactionManager.java:427) at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:371) at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:127) at org.apache.camel.processor.jpa.JpaRouteTest.cleanupRepository(JpaRouteTest.java:96) at org.apache.camel.processor.jpa.JpaRouteTest.createCamelContext(JpaRouteTest.java:67) at org.apache.camel.test.junit5.CamelTestSupport.doSetUp(CamelTestSupport.java:238) at org.apache.camel.test.junit5.CamelTestSupport.setUp(CamelTestSupport.java:208)
这里的问题是源代码是通过您的 IDE 而不是通过 Maven 编译或重新编译的,这会
-javaagent:<path_to_your_local_m2_cache>/org/apache/openjpa/openjpa/2.2.1/openjpa-2.2.1.jar
SPRING BOOT 自动配置
在 Spring Boot 中使用 jpa 时,请确保使用以下 Maven 依赖项来支持自动配置:
<dependency> <groupId>org.apache.camel.springboot</groupId> <artifactId>camel-jpa-starter</artifactId> <version>x.x.x</version> <!-- use the same version as your Camel core version --> </dependency>
该组件支持 8 个选项,如下所列。
姓名 | 描述 | 默认 | 类型 |
---|---|---|---|
camel.component.jpa.autowired-enabled | 是否启用自动装配。这用于自动自动装配选项(该选项必须标记为自动装配),通过在注册表中查找是否存在匹配类型的单个实例,然后在组件上进行配置。这可用于自动配置 JDBC 数据源、JMS 连接工厂、AWS 客户端等。 | true | Boolean |
camel.component.jpa.bridge-error-handler | 允许将消费者桥接到 Camel 路由错误处理程序,这意味着在消费者尝试获取传入消息或类似消息时发生的任何异常现在都将作为消息处理并由路由错误处理程序处理。默认情况下,消费者将使用 org.apache.camel.spi.ExceptionHandler 来处理异常,这些异常将被记录在 WARN 或 ERROR 级别并被忽略。 | false | Boolean |
camel.component.jpa.enabled | 是否启用 jpa 组件的自动配置。这是默认启用的。 | Boolean | |
camel.component.jpa.entity-manager-factory | 使用 EntityManagerFactory。强烈建议这样配置。该选项是 javax.persistence.EntityManagerFactory 类型。 | EntityManagerFactory | |
camel.component.jpa.join-transaction | camel-jpa 组件默认会加入事务。您可以使用此选项将其关闭,例如,如果您使用 LOCAL_RESOURCE 并且连接事务不适用于您的 JPA 提供程序。此选项也可以在 JpaComponent 上全局设置,而不必在所有端点上设置。 | true | Boolean |
camel.component.jpa.lazy-start-producer | 生产者是否应该懒惰地启动(在第一条消息上)。通过延迟启动,您可以使用它来允许 CamelContext 和路由在生产者可能在启动过程中失败并导致路由启动失败的情况下启动。通过延迟这个启动是惰性的,启动失败可以在通过 Camel 的路由错误处理程序路由消息期间处理。请注意,当处理第一条消息时,创建和启动生产者可能需要一些时间并延长处理的总处理时间。 | false | Boolean |
camel.component.jpa.shared-entity-manager | 是否为消费者/生产者使用 Spring 的 SharedEntityManager。请注意,在大多数情况下,joinTransaction 应设置为 false,因为这不是 EXTENDED EntityManager。 | false | Boolean |
camel.component.jpa.transaction-manager | 使用 PlatformTransactionManager 来管理事务。该选项是 org.springframework.transaction.PlatformTransactionManager 类型。 |