Spring JPA Cascade.ALL 不会删除父对象
Spring JPA Cascade.ALL won't delete parent object
我在此处 "Bidirectional many-to-many with link entity lifecycle" 学习此教程 https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#associations-many-to-many。但是,我使用的是 Spring JPA 而不是 Entity Manager。当我使用存储库界面删除地址时,即使我级联了 ALL,它也不会删除 PersonAddress 记录。它给了我外键约束异常。
"Referential integrity constraint violation: "FKCYC1KRSXQELKM4UWH65AVIJ23: PUBLIC.PERSON_ADDRESS 外键 (ADDRESS_ID) 引用 PUBLIC.ADDRESS(ID) (1)"; SQL 语句:"= 17=]
我的课程如下。
@Entity(name = "Address")
public class Address {
@Id
@GeneratedValue
private Long id;
private String street;
@Column(name = "number")
private String number;
private String postalCode;
@OneToMany(mappedBy = "address", cascade = {CascadeType.ALL}, orphanRemoval = true, fetch=FetchType.LAZY)
private List<PersonAddress> owners = new ArrayList<>();
PersonAddress.java
@Entity(name = "PersonAddress")
public class PersonAddress implements Serializable {
@Id
@ManyToOne
private Person person;
@Id
@ManyToOne
private Address address;
Person.java
@Entity(name = "Person")
public class Person{
@Id
@GeneratedValue
private Long id;
@NaturalId
private String registrationNumber;
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PersonAddress> addresses = new ArrayList<>();
Person和Address关联后删除地址的测试方法。这应该删除 PersonAddress 中的一条记录,因为 Address 有 Cascade.ALL 但它没有发生。我错过了什么?
@Test
@Transactional
public void testDeleteAddressAfterPatronAdd() {
Person person1 = new Person("ABC-123");
Person person2 = new Person("DEF-456");
Address address1 = new Address("12th Avenue", "12A", "4005A");
Address address2 = new Address("18th Avenue", "18B", "4007B");
Person savedPerson1 = personRepository.save(person1);
Person savedPerson2 = personRepository.save(person2);
Address savedAddress1 = addressRepository.save(address1);
Address savedAddress2 = addressRepository.save(address2);
personRepository.flush();
addressRepository.flush();
PersonAddress personAddress1 = new PersonAddress(savedPerson1, savedAddress1);
PersonAddress personAddress2 = new PersonAddress(savedPerson2, savedAddress2);
savedPerson1.getAddresses().add(personAddress1);
savedPerson2.getAddresses().add(personAddress2);
personRepository.flush();
addressRepository.flush();
Address loadedAddress1 = addressRepository.findById(savedAddress1.getId());
loadedAddress1.getOwners();
addressRepository.delete(loadedAddress1);
addressRepository.flush();
您没有正确维护关联的两侧。 personAddress1
引用了 address1
,但 address1
在其所有者列表中没有任何元素。
因此,当您删除 address1
时,Hibernate 不会将删除级联到任何所有者,因为列表中没有任何所有者。因此删除失败,因为您试图删除 PersonAddress
引用的 Address
,尽管 FK 约束。
我在此处 "Bidirectional many-to-many with link entity lifecycle" 学习此教程 https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#associations-many-to-many。但是,我使用的是 Spring JPA 而不是 Entity Manager。当我使用存储库界面删除地址时,即使我级联了 ALL,它也不会删除 PersonAddress 记录。它给了我外键约束异常。
"Referential integrity constraint violation: "FKCYC1KRSXQELKM4UWH65AVIJ23: PUBLIC.PERSON_ADDRESS 外键 (ADDRESS_ID) 引用 PUBLIC.ADDRESS(ID) (1)"; SQL 语句:"= 17=]
我的课程如下。
@Entity(name = "Address")
public class Address {
@Id
@GeneratedValue
private Long id;
private String street;
@Column(name = "number")
private String number;
private String postalCode;
@OneToMany(mappedBy = "address", cascade = {CascadeType.ALL}, orphanRemoval = true, fetch=FetchType.LAZY)
private List<PersonAddress> owners = new ArrayList<>();
PersonAddress.java
@Entity(name = "PersonAddress")
public class PersonAddress implements Serializable {
@Id
@ManyToOne
private Person person;
@Id
@ManyToOne
private Address address;
Person.java
@Entity(name = "Person")
public class Person{
@Id
@GeneratedValue
private Long id;
@NaturalId
private String registrationNumber;
@OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true)
private List<PersonAddress> addresses = new ArrayList<>();
Person和Address关联后删除地址的测试方法。这应该删除 PersonAddress 中的一条记录,因为 Address 有 Cascade.ALL 但它没有发生。我错过了什么?
@Test
@Transactional
public void testDeleteAddressAfterPatronAdd() {
Person person1 = new Person("ABC-123");
Person person2 = new Person("DEF-456");
Address address1 = new Address("12th Avenue", "12A", "4005A");
Address address2 = new Address("18th Avenue", "18B", "4007B");
Person savedPerson1 = personRepository.save(person1);
Person savedPerson2 = personRepository.save(person2);
Address savedAddress1 = addressRepository.save(address1);
Address savedAddress2 = addressRepository.save(address2);
personRepository.flush();
addressRepository.flush();
PersonAddress personAddress1 = new PersonAddress(savedPerson1, savedAddress1);
PersonAddress personAddress2 = new PersonAddress(savedPerson2, savedAddress2);
savedPerson1.getAddresses().add(personAddress1);
savedPerson2.getAddresses().add(personAddress2);
personRepository.flush();
addressRepository.flush();
Address loadedAddress1 = addressRepository.findById(savedAddress1.getId());
loadedAddress1.getOwners();
addressRepository.delete(loadedAddress1);
addressRepository.flush();
您没有正确维护关联的两侧。 personAddress1
引用了 address1
,但 address1
在其所有者列表中没有任何元素。
因此,当您删除 address1
时,Hibernate 不会将删除级联到任何所有者,因为列表中没有任何所有者。因此删除失败,因为您试图删除 PersonAddress
引用的 Address
,尽管 FK 约束。