java - Camel JMS 更新 JPA 实体

标签 java jpa apache-camel

当使用类似于下面的代码时,只要我从未有一条记录与之前的记录具有相同的主键,一切都可以,但是如果我收到一条具有相同主键的消息,我会得到一个无法插入异常。如果我得到具有相同主键的记录,是否可以设置 Jpa 将插入转换为更新?

from("jms:queue:myqueue")
    .unmarshal(myGsonDataFormat)
    .convertBodyTo(MyDBEntity.class)
    .to("jpa:" + MyDBEntity.class.getName());

@Entity
@Table(name = "MyTableName")
public class MyDBEntity {
    @Id
    @Column(name = "column1", length =2)
    private String column1;

    @Column(name = "column2", length =2)
    private String column2;

}

堆栈跟踪:

2016-03-15 15:12:04,766 [imer://fireOnce] ERROR DefaultErrorHandler            - Failed delivery for (MessageId: ID-WKSP000675FB-51972-1458069119050-0-5 on ExchangeId: ID-WKSP000675FB-51972-1458069119050-0-6). Exhausted after delivery attempt: 1 caught: <openjpa-2.4.1-r422266:1730418 nonfatal user error> org.apache.openjpa.persistence.InvalidStateException: Attempt to change a primary key field of an instance that already has a final object id.  Only new, unflushed instances whose id you have not retrieved can have their primary keys changed.
FailedObject: com.ups.ops.cipe.external.route.entity.RouteEntity-0000003

消息历史记录

---------------------------------------------------------------------------------------------------------------------------------------
RouteId              ProcessorId          Processor                                                                        Elapsed (ms)
[PackageCarStatusRo] [PackageCarStatusRo] [timer://fireOnce?repeatCount=1                                                ] [      3763]
[PackageCarStatusRo] [log2              ] [log                                                                           ] [         0]
[PackageCarStatusRo] [PersistRouteEntity] [jpa:com.ups.ops.cipe.external.route.entity.RouteEntity                        ] [      2354]

Exchange
---------------------------------------------------------------------------------------------------------------------------------------
Exchange[
    Id                  ID-WKSP000675FB-51972-1458069119050-0-6
    ExchangePattern     InOnly
    Headers             {breadcrumbId=ID-WKSP000675FB-51972-1458069119050-0-1, CamelRedelivered=false, CamelRedeliveryCounter=0, firedTime=Tue Mar 15 15:12:00 EDT 2016}
    BodyType            com.ups.ops.cipe.external.route.entity.RouteEntity
    Body                RouteEntity [driverId=0000003   , countryCode=US, slic=2029, lastUpdateTime=Tue Mar 15 15:12:02 EDT 2016, driverName=D3, routeName=07, allStopCompleted=0.0, allStopTotal=0.0, puPkgsCompleted=0.0, percentComplete=0.0]
]

堆栈跟踪

---------------------------------------------------------------------------------------------------------------------------------------
<openjpa-2.4.1-r422266:1730418 nonfatal user error> org.apache.openjpa.persistence.InvalidStateException: Attempt to change a primary key field of an instance that already has a final object id.  Only new, unflushed instances whose id you have not retrieved can have their primary keys changed.
FailedObject: com.ups.ops.cipe.external.route.entity.RouteEntity-0000003
    at org.apache.openjpa.kernel.StateManagerImpl.assertNoPrimaryKeyChange(StateManagerImpl.java:2185)
    at org.apache.openjpa.kernel.StateManagerImpl.settingStringField(StateManagerImpl.java:2166)
    at org.apache.openjpa.kernel.AttachStrategy.attachField(AttachStrategy.java:179)
    at org.apache.openjpa.kernel.VersionAttachStrategy.attach(VersionAttachStrategy.java:166)
    at org.apache.openjpa.kernel.AttachManager.attach(AttachManager.java:252)
    at org.apache.openjpa.kernel.AttachManager.attach(AttachManager.java:105)
    at org.apache.openjpa.kernel.BrokerImpl.attach(BrokerImpl.java:3508)
    at org.apache.openjpa.kernel.DelegatingBroker.attach(DelegatingBroker.java:1213)
    at org.apache.openjpa.persistence.EntityManagerImpl.merge(EntityManagerImpl.java:879)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:366)
    at com.sun.proxy.$Proxy69.merge(Unknown Source)
    at org.apache.camel.component.jpa.JpaProducer$1.save(JpaProducer.java:102)
    at org.apache.camel.component.jpa.JpaProducer$1.doInTransaction(JpaProducer.java:78)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131)
    at org.apache.camel.component.jpa.JpaProducer.process(JpaProducer.java:61)
    at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
    at org.apache.camel.processor.SendProcessor$2.doInAsyncProducer(SendProcessor.java:167)
    at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:304)
    at org.apache.camel.processor.SendProcessor.process(SendProcessor.java:162)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
    at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:662)
    at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:590)
    at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:237)
    at org.apache.camel.processor.Splitter.process(Splitter.java:104)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
    at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:662)
    at org.apache.camel.processor.MulticastProcessor.doProcessSequential(MulticastProcessor.java:590)
    at org.apache.camel.processor.MulticastProcessor.process(MulticastProcessor.java:237)
    at org.apache.camel.processor.Splitter.process(Splitter.java:104)
    at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
    at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:448)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:121)
    at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
    at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:191)
    at org.apache.camel.component.timer.TimerConsumer.sendTimerExchange(TimerConsumer.java:165)
    at org.apache.camel.component.timer.TimerConsumer$1.run(TimerConsumer.java:73)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)

最佳答案

您可以尝试使用参数usePersist=false

usePersist : 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)!

from("jms:queue:myqueue")
    .unmarshal(myGsonDataFormat)
    .convertBodyTo(MyDBEntity.class)
    .to("jpa:" + MyDBEntity.class.getName()+"?usePersist=false&flushOnSend=true&joinTransaction=true");

关于java - Camel JMS 更新 JPA 实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36013511/

相关文章:

java - 为什么人们继续使用 xml 映射文件而不是注释?

java - 具有动态路径的 Apache Camel 文件组件

java - 如何格式化无换行json文件?

java - 碰撞检测-避开盒子

java - JPA:选择实体的子集不会加载@OneToOne 属性

java - 如何在测试基于 CamelSpringTestSupport 的测试期间设置属性值

java - ContextLoaderListener 的问题

java - JUnit 测试未捕获异常

java - 在 Spring Boot 中为接口(interface)使用 @Autowired 注解

java - 如果找不到实体则为空对象