【问题标题】:JPA 2.x unidirectional one to many relationJPA 2.x 单向一对多关系
【发布时间】:2016-04-26 16:22:15
【问题描述】:

我想知道两个表之间是否可以存在一对多 jpa 2.x 关系。我正在寻找这样的东西: (我用谷歌搜索了很多以找出类似的场景但没有成功)

CUSTOMER
ID   NAME    RELATEDCOLORS
1    John    10
2    Albert  20
3    Maria   10
4    Smith   null

COLORS
ID   FATHERID   COLOR
1    10         Red
2    10         Green
3    10         Blu
4    20         Cyan

如您所见,每个人都有对应的颜色。所以,约翰和玛丽亚的颜色都是红色、绿色和蓝色。对于 Albert,颜色是青色,而对于 Smith,没有颜色。

我尝试过这样的事情:

客户实体

....
@Id
@Column(name = "ID", nullable = false)
private long iId;
@Column(name = "NAME")
private String iName;
@Column(name = "RELATEDCOLORS", nullable = true)
private Long iRelatedColors;
@JoinColumn(name = "FATHERID",referencedColumnName="RELATEDCOLORS", nullable=true)
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private List<Colors> iColors;
....

请注意,我使用的是“Long iRelatedColors”而不是“long iRelatedColors”,因为 iRelatedColors 属性可以为空

颜色实体

....
@Id
@Column(name = "ID", nullable = false)
private long iId;
@Column(name = "FATHERID", nullable = false)
private long iFatherId;
@Column(name = "COLOR")
private String iColor;
....

我不喜欢在 Colors 实体中拥有 Customer 类型的属性

我需要的是:

  • 读取客户时,当我调用相应的 get... 方法时,必须填充列表 iColor

  • 在 iColors 列表发生更改后更新客户时(例如:添加新颜色或删除颜色) 那么颜色实体也必须更新。

只有在以下情况下,我才拥有我所需要的一切:

  • 在 Customer 表中,RELATEDCOLORS 列使用唯一的数字填充(例如:10、20、30,40 ecc)

  • 在 Customer 表中,RELATEDCOLORS 列必须始终不为空,如果 Colors 表中有相应的 id 则无关紧要。 如果其中一个 CUSTOMER 行在 RELATEDCOLORS 列中具有空值,我在运行时会遇到休眠引发的 NullPointerException。

使用我向您展示的数据不起作用,我不明白为什么。

提前感谢您的帮助。

【问题讨论】:

  • 您的 OneToMany 映射会清楚地为颜色添加 FK,因此如果您不喜欢它,请删除该映射并放入 OneToOne/ManyToOne,FK 将在 Customer 中。
  • 关系表 Customer > Colors 显然是 @ManyToOne,所以我不确定您为什么要尝试将其映射为 @OneToMany??
  • 大家好,感谢您的回答。尼尔,你能更具体一点吗? Alan,从表格数据可以看出,Customers > Colors 之间的关系是 OneToMany。例如,Jhon 有红色、绿色和蓝色谢谢
  • 抱歉,我看不到任何类似的东西。如果 John 应该有一组颜色,那么应该有一个带有 customer_id color_id 的 Join 表。您的架构和映射毫无意义。

标签: hibernate jpa


【解决方案1】:

您的模型包含太多的不一致,实际上根本不常见。如果John 得到颜色Green, Blue and Cyan,你会怎么做?这意味着,除非表 COLORS 获得更多这样的数据,否则无法评估字段 RELATEDCOLORS,因为仍然存在颜色为 Red, Green and Blue 的 Maria:

COLORS
ID   FATHERID   COLOR
1    10         Red
2    10         Green
3    10         Blue
4    20         Cyan
5    30         Green
6    30         Blue
7    30         Cyan

这会导致大量冗余数据。您的Color-table 实际上几乎看起来像一个连接表,但不是。 除此之外,您的 OneToMany-Relation 是一个额外的连接表。

只需将您的颜色映射为单向 OneToMany,如下所示,然后去掉 Customer 中的 RELEATEDCOLORS 和 Color 中的 FATHERID:

@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.LAZY)
@JoinTable(name="CUSTOMER_COLORS", joinColumns={@JoinColumn(name="CUSTOMER_ID", referencedColumnName="iId")}, inverseJoinColumns={@JoinColumn(name="COLOR_ID", referencedColumnName="iId")})
private List<Color> iColors;

【讨论】:

    猜你喜欢
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-22
    • 2011-09-10
    • 1970-01-01
    • 2015-10-28
    • 1970-01-01
    相关资源
    最近更新 更多