Dan*_*ino 1 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]
Run Code Online (Sandbox Code Playgroud)
我保存产品并更新库存的方法:
@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));
}
Run Code Online (Sandbox Code Playgroud)
我的股票类别:
@Id
private String stockId:
@JsonBackReference
@OneToOne(cascade = {PERSIST, MERGE}, fetch = FetchType.LAZY)
@JoinColumn(name = "eancode")
@MapsId
private Product product;
Run Code Online (Sandbox Code Playgroud)
我的产品类别:
@JsonManagedReference
@OneToOne(cascade = {PERSIST, MERGE}, fetch = FetchType.LAZY, mappedBy = "product")
private Stock stock;
Run Code Online (Sandbox Code Playgroud)
您不应该以这种方式更新实体,这只适合创建新实体。
productRepo.save(prod)
Run Code Online (Sandbox Code Playgroud)
正确的方法是首先通过 id 加载实体(这会将对象附加到会话),更新它然后保存
Product existing = productRepo.findById(prod.getId());
existing.getStock().setCount(+prod.getStock().getCount());
productRepo.save(existing);
Run Code Online (Sandbox Code Playgroud)
但是在您的代码中,您收到具有现有 ID(!) 的“非托管”(未附加到休眠会话)对象,更新它并保存。当然会报错
| 归档时间: |
|
| 查看次数: |
7184 次 |
| 最近记录: |