Spring Data JPA - 删除一对多关系中的子项

3
我正在实施一个Spring Boot应用程序,并在其中使用Spring Data JPA。正如您所知道的那样,仅针对CRUD方法不必实现存储库接口,因为Spring Data JPA会动态创建实现。所以我只有这个:
public interface PersonRepository extends JpaRepository<Person, Long> {}

我正在处理一对多的关系,这是在我的“人物”域中:

@OneToMany(cascade = CascadeType.ALL,
        orphanRemoval = true,
        fetch = FetchType.LAZY,
        mappedBy = "person")
private Set<Contact> contacts = new HashSet<>();

我决定为从父级中删除子级编写一个集成测试:

    @Test
    public void removeFromContacts() {
    // given
    Person person = new Person ("test person");       
    Contact contact = new Contact("test@gmail.com", "+123456789");
    contact.setPerson(person);
    person.getContacts().add(contact);

    personRepository.save(person);

    Person savedPerson = personRepository.findOne(person.getId());
    Contact persistedContact = savedPerson.getContacts().stream().findFirst().orElse(null);

    // when
    savedPerson.getContacts().remove(persistedContact);
    persistedContact.setPerson(null);
    Person edited = personRepository.save(savedPerson);
    // then

    Assert.assertTrue(edited.getContacts().isEmpty());
}

这个测试失败了,原因是savedPerson.getContacts().remove(persistedContact)这一行没有改变任何东西,remove方法返回false。这很奇怪,因为我试图从一个只有一个对象具有完全相同哈希码(equals()方法也返回true)的哈希集中删除一个对象。根据这个答案,联系人对象可能在添加到哈希集之后被修改了。我唯一能想到的就是它发生在这行代码之后:personRepository.save(person)
如果我是正确的,那么我真的很困惑:我应该如何从一个人身上删除联系人,即使我找到了一种方法,personRepository.save方法引起集合出现故障是否可以呢?如果我错了,我很想知道正确的答案。
提前感谢。

不确定是否是这个问题,但尝试使用TestEntityManager保存,而不是您的Repository的save。Spring Data Repositories不会立即刷新实体。 - SrThompson
@SrThompson 刚刚尝试了一下,remove 方法仍然返回 false。 - V V
由于@OneToMany被联系记录上的person映射,这是否意味着持久化的人实际上没有联系人字段?我相信您需要保存联系人(在将人设置为null之后)以擦除关系。 - Brian
@Brian 我也试过了,但是如果它存在于 person.getContacts() 中,它仍然不会被删除。 - V V
1个回答

0

类Compte和类User建立了一对一的关系

public void delete(Integer integer){
    User user = userRepository.findOne(integer);
    Compte compte = user.getCompte();
    compte.setUser(null);
    compteRepository.save(compte);
    user.setCompte(null);
    userRepository.save(user);
    compteRepository.delete(compte);
    userRepository.delete(user);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接