无法使用Spring Integration删除JPA实体

时间:2013-10-07 17:37:15

标签: jpa spring-integration

当我尝试使用出站通道适配器删除实体时,我总是会删除一个分离的实例异常。 我知道应该在同一个事务中检索和删除一个实体以避免这个异常,但是如何通过Spring Integration实现呢?

为了演示我修改the JPA sample的问题:

PersonService.java

public interface PersonService {
    ...
    void deletePerson(Person person);
}

Main.java

private static void deletePerson(final PersonService service) {
    final List<Person> people = service.findPeople();
    Person p1 = people.get(0);
    service.deletePerson(p1);
}

弹簧整合-context.xml中

<int:gateway id="personService"
service-interface="org.springframework.integration.samples.jpa.service.PersonService"
    default-request-timeout="5000" default-reply-timeout="5000">
    <int:method name="createPerson" request-channel="createPersonRequestChannel"/>
    <int:method name="findPeople"   request-channel="listPeopleRequestChannel"/>
    <int:method name="deletePerson" request-channel="deletePersonChannel"/>
</int:gateway>

<int:channel id="deletePersonChannel"/>

<int-jpa:outbound-channel-adapter entity-manager-factory="entityManagerFactory"
channel="deletePersonChannel" persist-mode="DELETE" >
    <int-jpa:transactional transaction-manager="transactionManager" />
</int-jpa:outbound-channel-adapter>

当我调用deletePerson时,我得到了异常:

  

线程“main”中的异常java.lang.IllegalArgumentException:   删除分离的实例   org.springframework.integration.samples.jpa.Person#1001

更新

显然我应该选择一个离实际项目更近的样本,因为在这里你可以用编程方式创建一个新的事务,并将其中的检索和删除函数调用包装起来,就像Artem那样。

在我的项目中,我有一个连接到出站通道适配器的变压器。变换器检索实体,并且出站通道适配器将其删除。在这种情况下,如何让变换器和出站通道适配器使用相同的事务?

1 个答案:

答案 0 :(得分:2)

为了使其有效,您应该将deletePerson中的所有操作包装到事务中,例如

private static void deletePerson(final PersonService service) {
         new new TransactionTemplate(transactionManager)
       .execute(new TransactionCallbackWithoutResult() {

            protected void doInTransactionWithoutResult(TransactionStatus status) {
                 final List<Person> people = service.findPeople();
                 Person p1 = people.get(0);
                 service.deletePerson(p1);

            }
        });
}

在这种情况下,你应该以某种方式提供你的方法 transactionManager bean。

更新:

我在原始问题中向您展示了用例示例。 现在重新。 <transformer> - &gt; <jpa:outbound-channel-adapter>。 在此,您应该了解消息流的开始位置:

  1. 如果是<inbound-channel-adapter>有投票人,那么只需制作<poller> <transactional>
  2. 如果是<gateway>,谁调用<transformer>,那么只需用@Transactional
  3. 标记网关的方法
  4. 这是另一个交易建议技巧:Keep transaction within Spring Integration flow
  5. 在所有情况下,您都应该从<transactional>

    中删除<jpa:outbound-channel-adapter>