Reputation: 33
I am making a webshop in Java and I am currently working on the stock of the product. Everything is working fine, however I seem to get this confusing error which I don't know how to solve.
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]
My method which saves the product and updates the stock:
@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));
}
My Stock class:
@Id
private String stockId:
@JsonBackReference
@OneToOne(cascade = {PERSIST, MERGE}, fetch = FetchType.LAZY)
@JoinColumn(name = "eancode")
@MapsId
private Product product;
My Product class:
@JsonManagedReference
@OneToOne(cascade = {PERSIST, MERGE}, fetch = FetchType.LAZY, mappedBy = "product")
private Stock stock;
Upvotes: 1
Views: 7454
Reputation: 1159
Just for the ones that did not find the solution in the accepted answer - I have encountered the same Exception when introducing the VERSION column (via @Version annotation). I am posting this because in our case the Exception was misleading and it is possible that others to come across the same situation.
In more details, we introduced the VERSION column in order to address concurrent update issue. The problem came around because we already had some records that automatically got null when table was altered with the new column (which is an expected behavior, nothing wrong here). The thing we noticed was that the exception was triggered only when trying to update the rows for which the VERSION column was null.
We solved the issue by running a script which set VERSION column to 0 (zero) for the rows that had null.
Upvotes: 0
Reputation: 7521
You should not update entities in that way, this only fits for creating new entities.
productRepo.save(prod)
Correct way is to first load entity by id (this would attach object to session), update it and then save
Product existing = productRepo.findById(prod.getId());
existing.getStock().setCount(+prod.getStock().getCount());
productRepo.save(existing);
But in your code you receive "unmanaged" (that is not attached to hibernate session) object with existing ID (!), update it and save. Of course it would give an error
Upvotes: 5