Есть две сущности с отношением @ManyToOne и @OneToMany (категории и продукты). Когда я включаю (cascade=CascadeType.ALL), одна запись в «Продуктах» требует удаления одной категории, и это ПЛОХО. Что нужно сделать для этих объектов, чтобы в результате удаление происходило только в одном месте (таблица) без каскадного (связанного) удаления для другой ссылки??? Я использую Spring 5.1.5 (не Spring Boot) Спасибо!
SPRING 5 / TOMCAT 9 / JACKSON-DATABIND / spring-data-jpa 2.1.5 / persistence-api 1.0.2 / Hibernate-core 5.4.1
@Сущность категория общественного класса {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "CAT_ID")
private Long id;
@Column(name = "CAT_NAME")
private String name;
@JsonManagedReference
@OneToMany(cascade=CascadeType.ALL,fetch = FetchType.EAGER)
@JoinColumn(name = "CAT_ID")
@OrderBy
private Set<Product> products = new HashSet<>();
public Long getId() {
return id;
}
@Сущность продукт общественного класса {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name = "PRODUCT_ID")
private Long id;
@Column(name = "PRODUCT_NAME")
private String name;
@JsonBackReference
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "CAT_ID")
private Category category;
public Long getId() {
return id;
}
@RequestMapping(value="/categories/{categoryId}/products/{productId}", method=RequestMethod.DELETE) public ResponseEntity deleteById(@PathVariable Long categoryId, @PathVariable Long productId) { productService.deleteProductById(productId); вернуть новый ResponseEntity<>(HttpStatus.OK); }
@Transactional
@Override
public void deleteProductById(Long productId) {
// TODO Auto-generated method stub
productRepository.deleteById(productId);
}
Что ж, не устанавливайте cascade=CascadeType.ALL в Product.category, так как это именно то, что удаляет категорию при удалении продукта, а вы не хотите, чтобы это произошло. Код, который вы разместили, не удалит категорию при удалении продукта, поэтому я не уверен, в чем ваш вопрос.
Когда я отправляю DELETE локальный: 8080/весна-mvc-приложение/категории/1/продукты/1 , я хочу удалить продукт 1 (один), а не (нет) категории 1 (ОДИН)
И ваш код должен это делать. Что он на самом деле делает? Какова конкретная проблема с кодом, который вы разместили?
localhost:8080/spring-mvc-app/categories/1/products/1 - это не влияет. Но когда я добавляю cascade=CascadeType.ALL для объекта Product, я получаю возможность добавить продукт и связанную с ним категорию. Я просто хочу удалить продукт только без категории. Как это сделать?
cascade=CascadeType.ALL подразумевает, среди прочего, CascadeType.REMOVE. Если вы добавите cascade=CascadeType.ALL в объект Product для отношения категории, вы также добавите CascadeType.REMOVE, поэтому после удаления продукта связанная с ним категория также исчезнет. Так задумано, так в чем на самом деле ваша проблема?
localhost:8080/spring-mvc-app/categories/1/products/1 - это не влияет. Но когда я добавляю cascade=CascadeType.ALL для объекта Product, я получаю возможность добавить продукт и связанную с ним категорию. Я просто хочу удалить продукт только без категории. Как это сделать?
Замените cascade=CascadeType.ALL на {CascadeType.PERSIST, CascadeType.REFRESH, CascadeType.MERGE, CascadeType.DETACH}
Без изменений, попробуйте запустить на себя - github.com/д-р-Хофманн/весна-mvc-остальное




РЕШЕНО, не знаю почему, но в crudRepository метод deleteById(productId) работал только с CascadeType.ALL и вы удаляете все(записи товаров и категорий) в запросе /categories/{catId}/products/{productId} и это плохой. Я использую просто удалить (продукт продукта) и удалить этот продукт. В случае {id} просто запросите проект по идентификатору и получите его, затем удалите.
Я не уверен, что понимаю, чего вы пытаетесь достичь? Вы пытаетесь удалить оба связанных объекта без использования
(cascade=CascadeType.ALL)?