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上下文中查询,您将始终得到一个具有地址引用的人。