ManyToMany关系和保存对象

时间:2018-06-06 14:37:39

标签: java spring rest spring-data-jpa h2

我在两个实体之间有很多关系:团队。我创建了一种向团队添加人员的方法。

如果我只在一个服务(团队)中创建此方法,如果我有一个manyToMany关系,或者我是否需要在个人服务中创建相同的方法,我可以将人员添加到团队和团队吗?

这是我的方法:

public void addPersonsToTeams(Long teamId, Long personId) {
        Assert.notNull(personId, "Object can't be null!");
        Assert.notNull(teamId, "Object can't be null!");
        try {
            Person person = personRepository.getOne(personId);
            Team team = teamRepository.getOne(teamId);
            person.getTeams().add(team);
            personRepository.save(person);
        } catch (Exception e) {
            throw new CreateEntityException();
        }

    }

1 个答案:

答案 0 :(得分:0)

编辑来自https://stackoverflow.com/users/2224047/nikolay-shevchenko评论我明白,ORM框架本身可以解决多对多的同步问题。我还假设它会管理相关的锁定问题。无论如何我会先回答我的问题,因为我认为它仍然是一个很好的设计问题。

首先,如果生命周期不同,则应避免将一个对象包含在另一个对象中。您应该通过Id引用其他对象。你应该看看aggregate的概念。现在我不知道你使用的底层ORM将如何管理它。

具体来说,这是错误的imo

Team team = teamRepository.getOne(teamId);
person.getTeams().add(team);
personRepository.save(person);

因为(至少在代码中),您似乎将团队对象的副本存储在存储库中的人员中。但团队对象可以在此上下文之外进行修改。例如,团队可以有一个新人。然后,您的person对象将包含与存储在团队存储库中的团队对象不同步的团队对象。最终,您将在不同位置存储2个不同的团队对象。现在再次,如果您的ORM框架为您解决了这个问题,那么您可能会很好,但我认为您仍应考虑重新设计代码并避免让ORM解决这种困境。

我会编写类似这样的代码

if(teamRepository.contains(teamId)){
    person.getTeamIds().add(teamId);
    personRepository.save(person);
}

现在要让团队对象同步,您可以使用某种域事件。在团队服务中收听并在团队服务中进行相反的操作。但是,如果这种同步操作是在不同的事务中完成的,那么可能就是这种情况,那么这意味着在某些时候你的数据库不一致。这对您来说可能是个问题。如果你的后端在同步操作等之间崩溃会发生什么......

所以我认为你应该挑战你的设计以及团队和个人服务是分开的这一事实。也许他们是同一服务的一部分甚至是聚合,然后你可以同时更新它们?

这是一个庞大的设计问题,我建议看看什么是汇总,并阅读domain driven design

希望这会有所帮助:)

相关问题