无法使用Spring集成删除JPA实体

无法使用Spring集成删除JPA实体,jpa,spring-integration,Jpa,Spring Integration,当我尝试使用出站通道适配器删除实体时,总是会删除分离的实例异常。 我知道应该在同一事务中检索和删除一个实体以避免此异常,但是如何使用Spring集成实现它呢 要演示我修改的问题,请执行以下操作: PersonService.java public interface PersonService { ... void deletePerson(Person person); } Main.java private static void deletePerson(final Pe

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

要演示我修改的问题,请执行以下操作:

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);
}
private static void deletePerson(最终PersonService服务){
最终列表人员=service.findPeople();
人员p1=人员。获取(0);
服务人员(p1);
}
spring-integration-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所做的那样


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

要使其工作,您应该将所有操作包装在
deletePerson
to事务中,例如

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

            }
        });
}
private static void deletePerson(最终PersonService服务){
新建TransactionTemplate(transactionManager)
.execute(新建TransactionCallbackWithoutResult(){
受保护的void doInTransactionWithoutResult(事务状态){
最终列表人员=service.findPeople();
人员p1=人员。获取(0);
服务人员(p1);
}
});
}
在这种情况下,您应该以某种方式为您的方法transactionManagerbean提供支持

更新:

在最初的问题中,我向您展示了一个用例示例。 现在我们来<代码>->
。 在这方面,您应该了解消息流的起始位置:

  • 如果是使用轮询器进行的
    ,那么只需进行
  • 如果它是
    ,谁调用
    ,那么用
    @Transactional
    标记网关的方法就足够了
  • 这里还有一个事务性建议技巧:

  • 在任何情况下,您都应该从您的

    中删除
    ,谢谢Artem,它是有效的,但是有没有办法通过xml实现呢?再次感谢,#3帮助了我。关于#1和#2,我不想让整个流程成为事务性的。在我的例子中,流在tcp入站通道适配器中启动。在转换器之前,我有一个路由器,它决定执行哪个jpa操作。如果它决定删除,它将向转换器发送一条消息,只有它将有效负载转换为实体,并将其发送到jpa出站通道适配器进行删除。