命名空间支持
在使用XML命名空间支持时,底层解析器类会为您实例化相关的Java类。因此,通常您无需处理JPA适配器的内部工作机制。本节记录了Spring Integration提供的XML命名空间支持,并展示了如何使用XML命名空间支持来配置JPA组件。
通用 XML 命名空间配置属性
所有 JPA 组件共享某些配置参数:
auto-startup
生命周期属性,用于指示该组件是否应在应用程序上下文启动期间启动。默认为 true。可选。
id
标识底层的Spring bean定义,该定义是EventDrivenConsumer或PollingConsumer的实例。可选。
entity-manager-factory
适配器用于创建 EntityManager 的 JPA 实体管理器工厂引用。您必须提供此属性、entity-manager 属性或 jpa-operations 属性。
entity-manager
组件所使用的 JPA 实体管理器引用。您必须提供此属性、entity-manager-factory 属性或 jpa-operations 属性。
通常,您的 Spring 应用上下文仅定义一个 JPA 实体管理器工厂,而 EntityManager 是通过使用 @PersistenceContext 注解来注入的。这种方法不适用于 Spring Integration JPA 组件。通常,注入 JPA 实体管理器工厂是最佳选择,但当您想要显式注入一个 EntityManager 时,您必须定义一个 SharedEntityManagerBean。更多信息,请参阅相关的 Javadoc。
以下示例展示了如何显式包含一个实体管理器工厂:
<bean id="entityManager"
class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
<property name="entityManagerFactory" ref="entityManagerFactoryBean" />
</bean>
jpa-operations
对实现 JpaOperations 接口的 Bean 的引用。在极少数情况下,建议提供自定义的 JpaOperations 接口实现,而非依赖默认实现(org.springframework.integration.jpa.core.DefaultJpaOperations)。如果使用 jpa-operations 属性,则不得提供 JPA 实体管理器或 JPA 实体管理器工厂,因为 JpaOperations 已封装必要的数据源。
entity-class
实体类的完全限定名。此属性的确切语义根据我们执行的是 persist 或 update 操作,还是从数据库中检索对象而有所不同。
在检索数据时,你可以指定 entity-class 属性,以表明你希望从数据库中检索此类型的对象。在这种情况下,你不能定义任何查询属性(jpa-query、native-query 或 named-query)。
在持久化数据时,entity-class 属性用于指定要持久化的对象类型。如果在持久化操作中未指定该属性,系统将自动从消息的有效载荷中获取实体类。
jpa-query
定义要使用的 JPA 查询(Java Persistence Query Language)。
native-query
定义要使用的原生 SQL 查询。
named-query
指代一个命名查询。命名查询可以用原生 SQL 或 JPAQL 定义,但底层的 JPA 持久化提供程序会在内部处理这种区别。
提供 JPA 查询参数
要提供参数,你可以使用 parameter XML 元素。它提供了一种机制,允许你为基于 Java 持久化查询语言(JPQL)或原生 SQL 查询的查询提供参数。你也可以为命名查询提供参数。
基于表达式的参数
以下示例展示了如何设置基于表达式的参数:
<int-jpa:parameter expression="payload.name" name="firstName"/>
基于值的参数
以下示例展示了如何设置基于值的参数:
<int-jpa:parameter name="name" type="java.lang.String" value="myName"/>
位置参数
以下示例展示了如何设置基于表达式的参数:
<int-jpa:parameter expression="payload.name"/>
<int-jpa:parameter type="java.lang.Integer" value="21"/>
事务处理
所有 JPA 操作(例如 INSERT、UPDATE 和 DELETE)在执行时都需要一个活动的事务。对于入站通道适配器,您无需进行特殊处理。其配置方式与我们为其他入站通道适配器配置轮询器时使用事务管理器的方式类似。以下 XML 示例配置了一个事务管理器,该管理器与入站通道适配器一起使用轮询器:
<int-jpa:inbound-channel-adapter
channel="inboundChannelAdapterOne"
entity-manager="em"
auto-startup="true"
jpa-query="select s from Student s"
expect-single-result="true"
delete-after-poll="true">
<int:poller fixed-rate="2000" >
<int:transactional propagation="REQUIRED"
transaction-manager="transactionManager"/>
</int:poller>
</int-jpa:inbound-channel-adapter>
然而,在使用出站通道适配器或网关时,您可能需要显式启动事务。如果 DirectChannel 是出站适配器或网关的输入通道,并且当前执行线程中存在活动事务,则 JPA 操作将在同一事务上下文中执行。您也可以配置此 JPA 操作以新事务的方式运行,如下例所示:
<int-jpa:outbound-gateway
request-channel="namedQueryRequestChannel"
reply-channel="namedQueryResponseChannel"
named-query="updateStudentByRollNumber"
entity-manager="em"
gateway-type="UPDATING">
<int-jpa:parameter name="lastName" expression="payload"/>
<int-jpa:parameter name="rollNumber" expression="headers['rollNumber']"/>
<int-jpa:transactional propagation="REQUIRES_NEW"
transaction-manager="transactionManager"/>
</int-jpa:outbound-gateway>
在前面的示例中,出站网关或适配器的 transactional 元素指定了事务属性。如果适配器的输入通道是 DirectChannel,并且希望适配器在与调用方相同的事务上下文中执行操作,那么定义这个子元素是可选的。然而,如果使用 ExecutorChannel,则必须包含 transactional 元素,因为调用客户端的事务上下文不会被传播。
与轮询器(poller)的 transactional 元素(在 Spring Integration 命名空间中定义)不同,出站网关或适配器的 transactional 元素是在 JPA 命名空间中定义的。