Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 多个关系和保存对象_Java_Spring_Rest_Spring Data Jpa_H2 - Fatal编程技术网

Java 多个关系和保存对象

Java 多个关系和保存对象,java,spring,rest,spring-data-jpa,h2,Java,Spring,Rest,Spring Data Jpa,H2,我在两个实体之间有很多关系:团队和个人。我已经创建了一个方法来将一个人添加到团队中 如果我只在一个服务(团队)中创建此方法,如果我有多人关系,我是否可以将人员添加到团队和团队添加到人员,或者我是否需要在人员服务中创建相同的方法 这是我的方法: public void addPersonsToTeams(Long teamId, Long personId) { Assert.notNull(personId, "Object can't be null!"); A

我在两个实体之间有很多关系:团队个人。我已经创建了一个方法来将一个人添加到团队中

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

这是我的方法:

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();
        }

    }

编辑从评论中我了解到ORM框架可以自行解决多对多同步问题。我认为它也会管理相关的锁定问题。我会让我以前的答案无论如何,因为我认为这仍然是一个很好的设计问题

首先,如果一个对象具有不同的生命周期,则应避免将其包含到另一个对象中。您应该简单地通过Id引用另一个对象。您应该看看的概念。现在我不知道您正在使用的底层ORM将如何管理这一点

具体来说,这是错误的

Team team = teamRepository.getOne(teamId);
person.getTeams().add(team);
personRepository.save(person);
因为(至少在代码中)您似乎正在存储库中的人员中存储团队对象的副本。但是团队对象可以在此上下文之外进行修改。例如,团队可以有一个新人。然后,person对象将包含一个与团队存储库中存储的团队对象不同步的团队对象。最终,两个不同的团队对象存储在不同的位置。现在,如果您的ORM框架为您解决了这个问题,那么您可能是好的,但我认为您仍然应该考虑重新设计代码,避免让ORM解决这种困境。 我会编写类似这样的代码

if(teamRepository.contains(teamId)){
    person.getTeamIds().add(teamId);
    personRepository.save(person);
}
现在,要同步团队对象,可以使用某种域事件。在团队服务中聆听,并在团队服务中执行相反的操作。但是如果这个同步操作是在一个不同的事务中完成的,这可能就是这种情况,那么这意味着在某个点上,您的数据库是不一致的。这对你来说可能是个问题,也可能不是。如果您的后端在同步操作等之间崩溃,会发生什么情况

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

这是一个巨大的设计问题,我建议看看什么是聚合,并阅读相关内容


希望这会有所帮助:)

您是否在询问这是否能正确地将数据持久化到数据库中?另外,请为您正在使用的框架添加其他相关标记,如jpa、hibernate等。是的,来自这两个站点。所以我不需要在person服务中创建这种方法?假设您有一个联接表,这应该正确地向该联接表插入一个新条目,我认为这应该是您所需要的。但是,和往常一样,最好的确保方法是实际(测试)运行它。是的,我知道,但要运行它,我需要res-cotroller方法(我想是POST),但我不知道如何编写这种方法:/如果它运行成功,那就好了。如果它失败了,我们可以帮助您修复它。但是如果你不能运行它,那么我们就无能为力了。很抱歉。
因为您正在存储库中的人员中存储团队对象的副本
。多对多关系通常使用带有2个FK的联接表,因此没有“对象副本”。如果同一类的两个托管实例的ID相等,则Hibernate认为它们是同一个Instance。因此,您的示例没有ORM样式。这是真的,我不知道hibernate将如何做到这一点,我将重新措辞。然而,在我看来,假设hibernate将为您解决设计问题是一种不好的做法。