JPA (orphanRemoval = true) 实现
JPA (orphanRemoval = true) Implementation
我一直在阅读 JPA 中有关 orphanRemoval= true
的帖子。
根据文档:
orphanRemoval is a flag -
Whether to apply the remove operation to entities that have been
removed from the relationship and to cascade the remove operation to
those entities.
我还参考了 this article 以获取更多信息,他们试图将子实体(地址 - 在他们的示例中)设置为 null。
我目前知道制作 orphanRemoval= true
将执行与 cascade=CascadeType.REMOVE
类似的操作,如果我删除我的父实体,它也会删除子实体。
我想测试的是它带来的附加功能,即删除未被其父实体引用的实体。
我正在尝试创建一个类似的场景,其中我将新的电话集合设置为 new ArrayList<>()
,其中父实体是 Person。
以下是我的实体 classes .
Person.java
@Entity
@Table(name = "person")
@Data
public class Person {
@Id
int pd ;
String fname;
String lname;
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="person",orphanRemoval=true)
List<Phone> phones = new ArrayList<>() ;
public boolean addPhone(Phone phone) {
boolean added = this.phones.add(phone);
phone.setPerson(this);
return added;
}
}
Phone.java
@Entity
@Table(name = "phone")
@Data
public class Phone {
private int countryCode;
@Id
private String number ;
@ManyToOne
@JoinColumn(name="fk_person")
Person person ;
}
主要class
public void testFlow() {
Person p = fetchById(765);
p.setPhones(new ArrayList<>());
personRepo.save(p); **// exception on this line**
getPersons();
}
public Person fetchById(int id) {
Optional<Person> pe = personRepo.findById(id);
Person person = pe.get();
System.out.println("person is :"+ person.getFname());
System.out.println("cc is :"+ person.getPhones().get(0).getNumber());
return person;
}
public List<Person> getPersons() {
List<Person> persons = personRepo.findAll();
persons.forEach(p -> {
System.out.println("person :"+p.getPd());
System.out.println("person phones :"+p.getPhones().get(0).getNumber());
System.out.println("=================================");
});
return persons;
}
入口方法是testFlow() .
当我执行这段代码时,出现错误:
org.hibernate.HibernateException: A collection with
cascade="all-delete-orphan" was no longer referenced by the owning
entity instance: com.example.entity.Person.phones
有什么线索可以测试 orphanRemoval
的工作示例吗?
这是应该抛出异常的行:
personRepo.save(p);
它发生了,因为您正试图保存未引用任何 Phone
的 Person
。我的意思是,您仅取消引用 Person
而不是 Phone
实体。由于它是双向关系,因此您必须取消引用两者:
public void testFlow() {
Person p = fetchById(765);
p.getPhones().foreach(ph -> ph.setPerson(null));
p.setPhones(new ArrayList<>());
personRepo.save(p); **// exception on this line**
getPersons();
}
问题是由以下行引起的:
p.setPhones(new ArrayList<>());
在 Hibernate 中,如果关联已指定 orphanRemoval = true
,则无法覆盖从持久性上下文中检索到的集合。如果您的目标是最终得到一个空集合,请改用 p.getPhones().clear()
。
我一直在阅读 JPA 中有关 orphanRemoval= true
的帖子。
根据文档:
orphanRemoval is a flag -
Whether to apply the remove operation to entities that have been removed from the relationship and to cascade the remove operation to those entities.
我还参考了 this article 以获取更多信息,他们试图将子实体(地址 - 在他们的示例中)设置为 null。
我目前知道制作 orphanRemoval= true
将执行与 cascade=CascadeType.REMOVE
类似的操作,如果我删除我的父实体,它也会删除子实体。
我想测试的是它带来的附加功能,即删除未被其父实体引用的实体。
我正在尝试创建一个类似的场景,其中我将新的电话集合设置为 new ArrayList<>()
,其中父实体是 Person。
以下是我的实体 classes .
Person.java
@Entity
@Table(name = "person")
@Data
public class Person {
@Id
int pd ;
String fname;
String lname;
@OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="person",orphanRemoval=true)
List<Phone> phones = new ArrayList<>() ;
public boolean addPhone(Phone phone) {
boolean added = this.phones.add(phone);
phone.setPerson(this);
return added;
}
}
Phone.java
@Entity
@Table(name = "phone")
@Data
public class Phone {
private int countryCode;
@Id
private String number ;
@ManyToOne
@JoinColumn(name="fk_person")
Person person ;
}
主要class
public void testFlow() {
Person p = fetchById(765);
p.setPhones(new ArrayList<>());
personRepo.save(p); **// exception on this line**
getPersons();
}
public Person fetchById(int id) {
Optional<Person> pe = personRepo.findById(id);
Person person = pe.get();
System.out.println("person is :"+ person.getFname());
System.out.println("cc is :"+ person.getPhones().get(0).getNumber());
return person;
}
public List<Person> getPersons() {
List<Person> persons = personRepo.findAll();
persons.forEach(p -> {
System.out.println("person :"+p.getPd());
System.out.println("person phones :"+p.getPhones().get(0).getNumber());
System.out.println("=================================");
});
return persons;
}
入口方法是testFlow() .
当我执行这段代码时,出现错误:
org.hibernate.HibernateException: A collection with cascade="all-delete-orphan" was no longer referenced by the owning entity instance: com.example.entity.Person.phones
有什么线索可以测试 orphanRemoval
的工作示例吗?
这是应该抛出异常的行:
personRepo.save(p);
它发生了,因为您正试图保存未引用任何 Phone
的 Person
。我的意思是,您仅取消引用 Person
而不是 Phone
实体。由于它是双向关系,因此您必须取消引用两者:
public void testFlow() {
Person p = fetchById(765);
p.getPhones().foreach(ph -> ph.setPerson(null));
p.setPhones(new ArrayList<>());
personRepo.save(p); **// exception on this line**
getPersons();
}
问题是由以下行引起的:
p.setPhones(new ArrayList<>());
在 Hibernate 中,如果关联已指定 orphanRemoval = true
,则无法覆盖从持久性上下文中检索到的集合。如果您的目标是最终得到一个空集合,请改用 p.getPhones().clear()
。