【问题标题】:JPA using one join table for two OneToMany entityJPA 为两个 OneToMany 实体使用一个连接表
【发布时间】:2017-04-11 13:03:20
【问题描述】:

有一个实体类“A”(应该是一个人),还有另一个实体类“B”(应该是一个合同)。

实体“A”与“B”类有关系@OneToMany(一个人可以签署很多合同)。实体“B”还与“A”类有@OneToMany 关系(合同可以有很多人签署)。

在这种情况下,数据库中会有 2 个JoinTable,但实际上它们在某种程度上是相同的。

有没有我只使用 One JoinTable 来制作它们?

寻求帮助!

【问题讨论】:

  • 你不是在描述@ManyToMany 关系吗?
  • OneToMany 不需要任何 JoinTable。只有对于 ManyToMany,您才需要一个 JoinTable。为什么你认为你需要 2 个 JoinTables?
  • 是的,这是一个@MTM 关系。
  • @tak3shi ,但无论如何它都会在我的数据库中创建一个连接表

标签: java hibernate jpa hibernate-annotations


【解决方案1】:

看起来与我的 @ManyToMany 关系...

类人

@ManyToMany
@JoinTable(name="PERS_CONTRACTS")
public Set<Contract> getContracts() { return contracts; }

类合同

@ManyToMany(mappedBy="contracts")
public Set<Person> getSigners() { return signers; }

【讨论】:

  • 感谢您的回答,有没有像我的问题一样将 2 OneToMany 相互结合,而不是使用 2 OTM 但使用 1 个联接表的 MTM 关系,我知道这没有任何意义,但在那里也许是一种方式或想法?
  • 你为什么要这么做,@RezaPayambari?如果您真的想使用 2 个 OTM 关系,您可以创建一个名为“PersonContract”的实体,它表示数据库中的一个表,并且与 Person 和 Contract 具有 OTM 关系。 (一个人可以有很多个PersonContracts,一个合同也可以有很多个PersonContracts)
【解决方案2】:

通过使用两个 @OneToMany 没有 JoinTable。 你可以像这样使用@ManyToMany

@ManyToMany
  @JoinTable(
      name="AB",
      joinColumns=@JoinColumn(name="A_ID", referencedColumnName="ID"),
      inverseJoinColumns=@JoinColumn(name="B_ID", referencedColumnName="ID"))
  private List<B> bS;

【讨论】:

  • 有可能——尽管根本不常见——将 JoinTable 用于@OneToMany 关系
【解决方案3】:

它是一种多对多关系。所以它只需要一个像person_contract这样的联结表在数据库中。它将包含如下列:

  1. Person_id
  2. 合同编号

person_id 和 contract_id 都是复合唯一键。

在休眠状态下,它将是: 1. 在人表中

@ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "person_contract ", joinColumns = {
        @JoinColumn(name = "person_id", nullable = false, updatable = false) },
        inverseJoinColumns = { @JoinColumn(name = "contract_id",
                nullable = false, updatable = false) })
public Set<Contract> contracts;
  1. 在合同表中

    @ManyToMany(fetch = FetchType.LAZY, mappedBy = "contracts") public Set<Person> persons;

【讨论】:

    【解决方案4】:

    情况:

    你在这里把事情复杂化了,你的实体之间的适当关系应该是ManyToMany,因为:

    • person可以签很多contracts
    • contract可以被很多人签名persons

    在这种关系中的一个JoinTable 足以为您提供所有要求的详细信息:

    • 谁签署了给定的Contract
    • Contracts 有一个 Person 签名。

    映射:

    所以你的映射会是这样的:

    在您的Person 班级中:

    @ManyToMany(mappedBy = "persons")
    private Set<Contract> contracts= new HashSet<Contract>();
    

    在你的Contract 课堂上:

    @ManyToMany(cascade = CascadeType.ALL)
    @JoinTable(
            name = "PERSONS_CONTRACTS",
            joinColumns = @JoinColumn(name = "CONTRACT_ID"),
            inverseJoinColumns = @JoinColumn(name = "PERSON_ID")
    )
    private Set<Person> persons= new HashSet<Person>();
    

    您可以查看此Hibernate Many-to-Many Association Annotations Example 了解更多详情。

    【讨论】:

    • 感谢您的回答,有没有像我的问题一样将 2 OneToMany 相互结合,而不是使用 2 OTM 但使用 1 个联接表的 MTM 关系,我知道这没有任何意义,但在那里也许是一种方式或想法?
    • @RezaPayambari 我认为两个实体之间可以有两种关系(我自己从未尝试过),但这不会有多大用处和不合逻辑。但是您可以在每个实体中拥有另一个实体的 Setinstance of it. For example in your Person class you can have both Set 合同;` 和 Contract contract,然后调整映射以相应地映射每个实体。你必须尝试一下。 但是ManyToMany 这里真的足够了,回答了你的问题。
    • 嘿,感谢您的提示。'ManyToMany' 在这种情况下帮助了我,但我需要使用 'OneToMany' 来做到这一点。
    猜你喜欢
    • 1970-01-01
    • 2013-11-27
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多