我正在开发一个Spring应用程序,该应用程序在尝试在我的一个表中运行更新时给我一些问题,而我无法弄清楚问题的根源。尝试运行更新时,我收到此错误:
org.hibernate.HibernateException:拥有实体实例com.client.product.Product.shipments
不再引用带有cascade =“ all-delete-orphan”的集合我最终要调用相同的保存方法来创建新产品和更新现有产品,并且错误仅在更新时发生。新建一个可以100%优良。
产品类别如下:
@Entity
@Data
@Cache( usage = CacheConcurrencyStrategy.READ_WRITE )
@ToString(exclude = {"shipments"})
@EqualsAndHashCode(exclude = {"shipments"})
@JsonFilter("NoShipmentFilter")
public class Product extends AbstractEntity {
//Other fields here
@OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ShipmentProduct> shipments = new ArrayList<>();
//Other methods here
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Product product = (Product) o;
return Objects.equals(id, product.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
}
ProductShipment类(联接表)如下:
@Entity(name = "ShipmentProduct")
@Table(name = "shipment_product")
public class ShipmentProduct {
@EmbeddedId
private ShipmentProductId id;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("productId")
@JsonIgnore
private Product product;
@ManyToOne(fetch = FetchType.LAZY)
@MapsId("shipmentId")
@JsonIgnore
private Shipment shipment;
@Column(name="quantity")
private Integer quantity;
@Column(name = "created_on")
private Date createdOn = new Date();
public ShipmentProduct() {}
public ShipmentProduct(Product product, Shipment shipment) {
this.product = product;
this.shipment = shipment;
this.id = new ShipmentProductId(product.getId(), shipment.getId());
}
public ShipmentProductId getId() {
return id;
}
//Getters & Setters here
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
ShipmentProduct that = (ShipmentProduct) o;
return Objects.equals(product, that.product) &&
Objects.equals(shipment, that.shipment);
}
@Override
public int hashCode() {
return Objects.hash(product, shipment);
}
}
Shipment类中的列注释如下:
@OneToMany(mappedBy = "shipment", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ShipmentProduct> products = new ArrayList<>();
产品的serviceImpl具有以下更新:
@Override
public Product save(Client client, Product product) {
if( !client.getProductById(product.getId()).isPresent() ){
client.addProduct(product);
}
/*
The following line is where the error gets thrown
*/
Product savedProduct = productRepository.save(product);
/*
This works 100% fine when saving a new product, only the update fails
*/
clientRepository.save(client);
return savedProduct;
}
@Override
public Product update(Client client, Product incoming, Product current){
return save(client, current.copyFields(incoming, "client"));
}
而且,来自控制器的实际调用看起来像这样:
@PutMapping("/{productId}")
@PreAuthorize("hasAuthority('ADMIN')")
public ResponseEntity<MappingJacksonValue> update(@PathVariable("clientId") Optional<Client> client,
@PathVariable("productId") Optional<Product> current, @RequestBody Product incoming){
if( client.isPresent() && current.isPresent() && current.get().isAssociated(client.get()) ){
FilterProvider filters = new SimpleFilterProvider().addFilter("apiFilter", SimpleBeanPropertyFilter.serializeAllExcept());
Product product = productService.update(client.get(), incoming, current.get());
MappingJacksonValue mapping = new MappingJacksonValue(product);
mapping.setFilters(filters);
return new ResponseEntity<>(mapping, HttpStatus.OK);
}else {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}