【发布时间】:2018-04-02 22:50:26
【问题描述】:
我正在实现一个 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)。根据this 的回答,在将联系人对象添加到散列集后,可能会以某种方式对其进行更改。我唯一能想到的是它发生在这行之后:personRepository.save(person)。
如果我是对的那么我真的很困惑:我应该如何从一个人身上删除联系人,即使我找到了方法,personRepository.save 方法是否可以导致设备故障?如果我错了,我很想知道正确的答案。
提前致谢。
【问题讨论】:
-
不确定这是否是问题所在,但请尝试使用
TestEntityManager而不是存储库的save进行保存。 Spring Data Repositories 不会立即刷新实体 -
@SrThompson 刚刚尝试过,
remove方法仍然返回 false。 -
既然
@OneToMany是由person在联系人记录上映射的,这是否意味着持久化的人实际上没有联系人字段?我相信您需要保存联系人(在将人员设置为null后)以删除关系 -
@Brian 我也试过了,但如果它存在于
person.getContacts()中,它不会删除
标签: java spring-data-jpa integration-testing