我一直在阅读有关JPA中orphanRemoval= true的帖子。
根据文件:


  orphanRemoval是一个标志-
  
  是否将删除操作应用于已被删除的实体
  从关系中删除,并将删除操作级联到
  这些实体。


我也参考了this article以获得更多信息,他们尝试将子实体(在示例中为address)设置为null。

我目前了解制作orphanRemoval= true会执行与cascade=CascadeType.REMOVE类似的操作,并且如果删除父实体,也会删除子实体。

我要测试的是它带来的附加功能,即删除未由其父实体引用的实体。

我正在尝试创建一个类似的场景,其中将新的手机集合设置为new ArrayList<>(),其中父实体是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;
    }
}


电话.java

@Entity
@Table(name = "phone")
@Data
public class Phone {
    private int countryCode;
    @Id
    private String number ;

    @ManyToOne
    @JoinColumn(name="fk_person")
    Person person ;

}


主班

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:具有的集合
  拥有者不再引用cascade =“ all-delete-orphan”
  实体实例:com.example.entity.Person.phones


有什么线索可以测试orphanRemoval的工作示例吗?

最佳答案

该问题是由以下行引起的:

p.setPhones(new ArrayList<>());


在Hibernate中,如果关联已指定orphanRemoval = true,则不能覆盖从持久性上下文中检索到的集合。如果您的目标是得到一个空集合,请改用p.getPhones().clear()

08-05 07:37