Это всегда было проблемой обработки каскадов в JPA или Hibernate, но я действительно не получил его сейчас.JPA CascadeType.All не удаляет родительские и дочерние строки
Я хочу удалить марку родительской строки и дочерние элементы, ссылающиеся на нее. Я использовал CascadeType.ALL, но не повезло.
Вот мои модели (Transact < - TransactProduct -> Продукция -> Brand -> Клиент), я показываю только отношения для ясности:
@Entity
@Table(name = "customer")
public class Customer {
@OneToMany(fetch = FetchType.EAGER, mappedBy = "customer", cascade = CascadeType.ALL)
private Collection<Brand> brands;
}
@Entity
@Table(name = "brand")
public class Brand implements Serializable {
@ManyToOne
@JoinColumn(name = "customer_id")
private Customer customer;
@OneToMany(mappedBy = "brand", cascade = CascadeType.ALL)
private Collection<Product> products;
}
@Entity
@Table(name = "product")
public class Product {
@ManyToOne
@JoinColumn(name = "brand_id")
private Brand brand;
@OneToMany(mappedBy = "product", cascade = CascadeType.ALL)
private Collection<TransactProduct> transactProducts;
}
@Entity
@Table(name = "transact")
public class Transact {
@OneToMany(mappedBy = "transact", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Collection<TransactProduct> transactProducts;
@ManyToOne
@JoinColumn(name = "user_id")
private User user;
}
@Entity
@Table(name = "transact_product")
public class TransactProduct {
@ManyToOne
@JoinColumn(name = "product_id")
private Product product;
@ManyToOne
@JoinColumn(name = "transact_id");
private Transact transact;
}
Марка Repository:
@Repository
public interface BrandRepository extends JpaRepository<Brand, Long> {}
В моем контроллере я хочу удалить такой бренд:
Brand brand = brandRepository.findOne(id);
brandRepository.delete(brand);
После findOne it wr ИТЭС те утешать:
select * from brand brand0_ left outer join customer customer1_ on brand0_.customer_id=customer1_.id where brand0_.id=?
select * from brand brands0_ where brands0_.customer_id=?
И после того, как удалить это:
select * from brand brand0_ left outer join product products1_ on brand0_.id=products1_.brand_id where brand0_.id=?
select * from customer customer0_ left outer join brand brands1_ on customer0_.id=brands1_.customer_id where customer0_.id=?
Он даже не запустить запрос на удаление. Что делать, чтобы удалять бренды и каскадировать эти процессы удаления на продукты и транзакт продуктов, ссылающихся на него? Я использую CascadeType.All, но он не работает.
Спасибо.
EDIT: Я добавил модель моего покупателя к вопросу. А также хочу отметить, что, когда я удалить объект клиента с помощью:
customerRepository.delete(id);
это делает,
delete from brand where id=?
delete from customer where id=?
Я добавил orphanRemoval к Брэнд сущности, как Энди Dufresne упоминается, но это не сработало. Может быть, это потому, что у бренда также есть родительский объект? Потому что, когда я использую тот же метод для удаления клиентов, он просто работает. И объект клиента не имеет родителя.
Я рад, что вы решили свою проблему. Он должен работать из коробки с помощью 'orphanRemoval = true'. Если вы хотите ответить, у вас есть '@ Transactional' на вашем контроллере и работает правильно? Поскольку удаление сироты будет обработано в entityManager.flush(). Я просто немного странно не работает, как с удалением сироты. –
Я добавил и протестировал, но ничего не изменилось. Как я понял, проблема заключается не только в том, что сиротская сеть удаляется. Родитель (бренд) также не был удален. Как упоминалось в моем ответе, я думаю, что это связано с тем, что у бренда также есть родитель (клиент). Возможно, jpa ожидает, что мы сначала удалим его родителя. – cuneytyvz
Как я пишу комментарий, у меня появилась идея. Я попытался удалить FetchType.EAGER из объекта Customer, после чего он сработал! Но мне нужно было добавить @Transactional, как вы сказали. Фактически, удаление EAGER несколько напоминает удаление клиента из бренда (родителя от ребенка). Причина, по которой он не удаляется, состоит в том, что у него есть родитель. И это требует Transactional. Но это не имеет смысла для меня, потому что мы должны иметь возможность удалять детей независимо от того, имеет ли он родителя или нет. – cuneytyvz