休眠错误与更新具有多对多字段的表有关

时间:2019-05-25 17:54:47

标签: spring hibernate

我正在开发一个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);
    }
}

0 个答案:

没有答案