Hibernate Spring JPA会话:具有相同标识符值的不同对象已与会话关联

时间:2018-03-27 07:43:57

标签: java spring hibernate jpa

我正在用Java创建一个网上商店,我目前正在研究该产品的库存。一切都很好,但我似乎得到了这个令人困惑的错误,我不知道如何解决。

javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [nl.scalda.platenbaas.model.Stock#0191400002005]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:118) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:157) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:164) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:916) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:875) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.engine.spi.CascadingActions$6.cascade(CascadingActions.java:261) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:467) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:392) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:193) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:126) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.cascadeOnMerge(DefaultMergeEventListener.java:461) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:327) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:170) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:883) ~[hibernate-core-5.2.12.Final.jar:5.2.12.Final]

我保存产品并更新库存的方法:

@PostMapping("/products")
public ResponseEntity<Product> save(@RequestBody Product prod) {
    if (!productRepo.existsById(prod.getEancode())) {
        return ResponseEntity.ok().body(productRepo.save(prod));
    }
    prod.getStock().setCount(+prod.getStock().getCount());

    return ResponseEntity.ok().body(productRepo.save(prod));
}

我的股票类:

@Id
private String stockId:

@JsonBackReference
@OneToOne(cascade = {PERSIST, MERGE}, fetch = FetchType.LAZY)
@JoinColumn(name = "eancode")
@MapsId
private Product product;

我的产品类:

@JsonManagedReference
@OneToOne(cascade = {PERSIST, MERGE}, fetch = FetchType.LAZY, mappedBy = "product")
private Stock stock;

1 个答案:

答案 0 :(得分:2)

您不应该以这种方式更新实体,这仅适用于创建新实体。

ion-datetime

正确的方法是首先按id加载实体(这会将对象附加到会话),更新它然后保存

productRepo.save(prod)

但是在您的代码中,您会收到&#34; unmanaged&#34; (没有附加到hibernate会话)对象具有现有ID(!),更新并保存。当然会产生错误