Java 删除的实体在相关实体的列表中,但我可以';无法通过存储库找到它
我有以下代码:Java 删除的实体在相关实体的列表中,但我可以';无法通过存储库找到它,java,java-8,spring-data,spring-data-jpa,Java,Java 8,Spring Data,Spring Data Jpa,我有以下代码: @Transactional public void delete(String id) { PersonEntity personEntity = personRepository.findOne(id); //has one address with ID = 10 personEntity.getAddresses().stream().forEach(address -> addressRepository.delete(add
@Transactional
public void delete(String id) {
PersonEntity personEntity = personRepository.findOne(id);
//has one address with ID = 10
personEntity.getAddresses().stream().forEach(address -> addressRepository.delete(address.getId()));
PersonEntity personEntity2 = personRepository.findOne(id);
// not empty - I can see that are existing one address with ID = 10
personEntity2.getAddresses();
// ID = 10, but here is null
addressRepository.findOne(10);
}
为什么我可以在相关实体的列表中看到已删除的实体,但当我将
findOne
与此ID
一起使用时,方法返回null
?不要调用delete方法,只需从列表中删除实体即可。jpa将在事务完成后负责删除。或者您可以在删除后执行entityManager.flush()。这就是jpa的工作原理:
在您的delete
中,您删除了一个人的所有地址。准确地说,您将地址从JPA托管上下文中删除。这就是为什么调用addressRepository.findOne(10)
(甚至在事务提交之前)时会得到null
,因为这些地址在JPA上下文和ymore中不存在。当事务最终提交时,地址将从数据库中删除(而不是更早)
由于不从地址的人员列表中删除地址,因此即使被引用的实体在数据库中不再有相应的记录,它们仍将保留在那里(在事务提交之前和之后)
若要将数据库中的删除内容再次反映给您的个人,您可以调用entitymanager.refresh(personEntity)
,如果事务提交后您已经有一个未关闭的entity manager会话,或者只需再次调用personEntity=personRepository.findOne(id)
@Vikram Singh已经提出了一个更优雅的解决方案。要使此功能正常工作,您还需要使用orhapn removation=true
@OneToMany(orphanremovation=true
)将个人与地址之间的关系映射到一起。这不是我问题的答案。我不是问怎么做——我是问在我删除地址后,我是怎么打电话给findOne的<代码>PersonEntity personEntity2=personRepository.findOne(id)代码>和地址列表仍然不是空的,所以我不知道您的答案是否正确。您在哪里调用了PersonEntity personEntity2=personRepository.findOne(id)
。如果在delete
方法中,地址仍然不会从数据库中删除,并且人员也不会在JPA上下文中被修改(只删除引用的地址),因此,如果人员仍然拥有地址,则引用将是预期的行为。如果在提交事务后调用,则取决于实体管理器会话是否关闭。如果没有,请尝试entitymanager.refresh()。如果是,打开一个新会话并再次调用personRepository.findOne(id)
。在我的问题中,我描述了在哪里。好的,所以数据库中的引用被删除了,但是Person
侧的List
中的引用没有被刷新,是吗?如果您需要一个在delete
方法中没有引用地址的人,唯一的方法是在@…ToMany
映射中使用orphaneremovation=true
,并从列表中删除地址,而不是通过存储库删除地址。原因是:在JPA上下文中,人没有被修改(只有地址被修改)。所以,如果从数据库或JPA上下文中查询,您将始终得到一个具有地址引用的人。