Ошибка спящего режима, связанная с обновлением таблицы с полем «многие ко многим» - PullRequest
0 голосов
/ 25 мая 2019

Я работаю над приложением Spring, которое вызывает у меня проблемы при попытке запустить обновление в одной из моих таблиц, и я не могу понять, откуда возникла проблема.При попытке запустить обновление я получаю эту ошибку:

org.hibernate.HibernateException: коллекция с cascade = "all-delete-orphan" больше не упоминалась экземпляром объекта-владельца: com.client.product.Product.shipments

В итоге я вызываю один и тот же метод сохранения как для создания нового продукта, так и для обновления существующего, и ошибка возникает только при обновлении.Создание нового отлично работает на 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);
}
}

примечание к столбцу в классе Отправка выглядит следующим образом:

@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);
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...