【问题标题】:Why we need repeat ManyToOne annotation if the other is OneToMany in JPA?如果另一个是 JPA 中的 OneToMany,为什么我们需要重复 ManyToOne 注释?
【发布时间】:2022-01-10 20:42:18
【问题描述】:

我想了解为什么JPA在Mapping中需要双重注解,在优势类中需要OneToMany,在较弱类中需要ManyToOne,如果Event是ManyToOne,Category是OneToMany。

@Entity
@Table(name = "event")
public class Event {

    @ManyToOne
    @JoinColumn(name = "category_id")
    private Category category;

    public Category getCategory() {
        return category;
    }
}
@Entity
@Table(name = "category")
public class Category {

    @OneToMany
    @JoinColumn(name = "category_id")
    private List<Event> events;

    public List<Event> getEvents() {
        return events;
    }
}

【问题讨论】:

    标签: java jpa spring-data-jpa


    【解决方案1】:

    JPA 不需要任何双重映射。它实际上只需要@ManyToOne 关系。为什么?如果您认为数据库方面,在您称为 weaker 类的此类关系中,实现该关系的方法通常是添加类似列(在您的情况下为伪信息):

    category_id BIGINT REFERENCES 类别(id)

    JPA 知道由于注释 @ManyToOne 和(实现)能够生成外键等。

    但是@OneToMany 不是必需的。除了在需要时选择内容之外,它通常不会以任何方式影响数据库。它只是在 Java 端填充列表并获取与 stronger 类具有相同 stronger_id 的所有 weaker 行。可以说这是一种无需任何额外查询即可填充 weaker 列表的便捷方式。

    More to read

    【讨论】:

      【解决方案2】:

      补充@Pirho 所说的内容。 JPA 不需要重复映射——事实上,一些 JPA 提供程序会标记您发布的代码并抛出警告和异常,概述这是一个问题。您已将 Category 和 Event 设置为都具有 JoinColumn 定义,因此这两个映射都控制 Event.category_id 列。这不应该被允许,因为您会遇到特定事件实例可以引用 CategoryA,但在 CategoryB 的事件列表中的情况。然后数据库中发生的事情是未定义的,因为只有一个 Event.category_id 外键。没有占主导地位的映射类型或类的概念。

      可能的意思更像是:

      public class Event {
          @ManyToOne
          @JoinColumn(name = "category_id")
          private Category category;
      }
      
      public class Category {
          @OneToMany(mappedBy="category")
          private List<Event> events;
      }
      

      这称为双向关系,因为您可以从对象模型的两侧遍历它。但是,在数据库中,只有 Event.category_id,它由 Event.category 引用/关系控制/拥有。如果您将 Event.category 设置为不同的 Category 实例,JPA 将更新外键 - 您可以适当地设置 Category 实例,以便内存中的实例与数据库不同步。否则,它们可能会过时,直到重新加载。类别,在查询中使用它,甚至合并/持久/删除

      但没有必要这样做。您可以从任一侧将其映射为单向关系:

      public class Event {
          @ManyToOne
          @JoinColumn(name = "category_id")
          private Category category;
      }
      

      如果 Event.category 关系不存在,则从另一端:

      public class Category {
          @OneToMany
          @JoinColumn(name = "category_id")
          private List<Event> events;
      }
      

      已经有few questions 接触了这个

      【讨论】:

        猜你喜欢
        • 2011-02-17
        • 2020-11-26
        • 2017-12-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-17
        • 1970-01-01
        相关资源
        最近更新 更多