Issue
I have a Customer class where each customer can have multiple Products. The class is as follow:
@Entity
@Table(name = "customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private Long id;
@Column(name = "firstName")
private String firstName;
@Column(name = "lastName")
private String lastName;
@OneToMany(targetEntity=Product.class, mappedBy = "customer", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
@JsonManagedReference
private List<Product> products = new ArrayList<>();
//getters and setters here
}
and the Product class holds OneToOne relation with other Classes and it is as follows:
@Entity
@Table(name = "product")
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToOne(targetEntity=Customer.class, fetch = FetchType.LAZY)
@JoinColumn(name = "customer_id")
@JsonBackReference
private Customer customer;
@OneToOne(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
@JsonManagedReference
private SomeType1 someType1;
@OneToOne(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
@JsonManagedReference
private SomeType2 someType2;
@OneToOne(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
@JsonManagedReference
private SomeType3 someType3;
@OneToOne(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.LAZY)
@PrimaryKeyJoinColumn
@JsonManagedReference
private SomeType4 someType4;
//getters and setters here
}
I am trying to achieve following functionality with this:
Given Customer ID and Product ID, update the values in SomeType1, SomeType2, SomeType3
classes. I am getting the updated SomeType1, SomeType2, SomeType3
objects from UI and I want to update the values in DB. I already have PUT
method in place for this.
Here's the PUT
method:
@PutMapping(value = "customer/{id}/product/{product_id}")
@ResponseBody
public ResponseEntity<Product> updateProduct(@PathVariable final String id,
@PathVariable final String product_id, @RequestBody final Product product) {
Optional<Customer> customerInDb = customerService.getCustomerById(id);
if (!customerInDb.isPresent()) {
throw new ResponseStatusException(HttpStatus.NOT_FOUND,
MessageFormat.format("Customer with id {0} does not exist.", id));
} else {
product.setId(Long.valueOf(product_id));
product.setCustomer(customerInDb.get());
Product savedProduct = customerService.createProduct(product);
return ResponseEntity.ok(savedProduct);
}
}
I am getting following error for this REST call:
javax.persistence.EntityExistsException: A different object with the same identifier value was already associated with the session : [com.myapp.arg.entities.SomeType2#12]
What could be the reason for this?
createProduct method:
@Override
public Product createProduct(Product product) {
Product savedProduct = productRepository.save(product);
return savedProduct;
}
JSON input to the PUT
method:
{
"id":9,
"someType1":{
"id":9,
"avg":20,
"total":20
},
"someType2":{
"id":9,
"circum":45.0,
"strength":45.0,
"totalNav":0.0
},
"someType3":{
"id":9,
"tensile":87,
"pull":128,
"push":56,
"upward":28.0
},
"measuredBy":"SJ",
"addedDate":"2021-05-23",
"type":"Prime"
}
Solution
you are using the same id for all of your entities. ID must be unique
Answered By - J Asgarov