【发布时间】:2021-07-28 16:13:34
【问题描述】:
我有一组非常简单的表格来模拟多对多关系。
Foo -< FooBar >- Bar
当我选择数据时工作正常,但当我尝试创建关系的新实例时,我可能会收到错误,因为 JPA 正在尝试插入空值。
我必须同时设置 @ManyToOne 值和键(代表相同的东西),这让我觉得设置不正确。
因此,问题是如何正确设置注释以创建新的FooBar 关系?
实体
@Entity
@Table(name = "FOO")
public class Foo implements Serializable {
@Id
@Column(name = "FOO_ID")
private int id;
@column(name = "FOO_DESC")
private String desc;
@OneToMany(mappedBy = "foo")
private List<FooBar> fooBars;
//getters / setters / hashCode / equals
}
@Entity
@Table(name = "BAR")
public class Bar implements Serializable {
@Id
@Column(name = "BAR_ID")
private int id;
@column(name = "BAR_DESC")
private String desc;
@OneToMany(mappedBy = "bar")
private List<FooBar> fooBars;
//getters / setters / hashCode / equals
}
交集表(和键)
@Embeddable
public class FooBarKey implements Serializable {
private int fooId;
private int BarId;
//getters / setters / hashCode / equals
}
@Entity
@Table(name ="FOO_BAR_XREF")
public class FooBar implements Serializable {
@EmbeddedId
private FooBarKey key;
@MapsId("fooId")
@ManyToOne
@JoinColumn(name = "FOO_ID", referencedColumnName = "FOO_ID")
private Foo foo;
@MapsId("barId")
@ManyToOne
@JoinColumn(name = "BAR_ID", referencedColumnName = "BAR_ID")
private Bar bar;
@Column(name = "DESC")
private String desc;
//getters / setters / hashCode / equals
}
创建关系
最后我正在创建一个新的交集实例:
//foo and bar exist and are populated
FooBar fb = new FooBar();
FooBarKey fbk = new FooBarKey();
fbk.setFooId(foo.getId());
fbk.setBarId(bar.getId());
fb.setKey(fbk);
fb.setDesc("Some Random Text");
entityManager.persist(fb);
此时 JPA 错误提示它无法将 null 插入 FOO_ID。
我已经检查并在我持久化对象时,键填充了 Foo 和 Bar ID。
如果我添加
fb.setFoo(foo);
fb.setBar(bar);
在persist 之前它可以工作,但@MapsId 是否应该有效地告诉JPA 使用密钥进行映射?
我认为我应该同时设置 @ManyToOne 和键值,它们在逻辑上是相同的,所以我必须有一些配置不正确?
如果有什么不同,我正在使用 Eclipselink。
【问题讨论】:
-
它为空,因为关系为空。设置关系,而不是使用 MapsId 时的基本键映射 - MapsId 告诉 JPA 关系控制并将设置外键及其指向的基本映射,而不是相反。当您在同一事务中创建新的 Foo、FooBar 和 bar 时,如果稍后使用排序,ID 可能不存在,因此 getId 可能为空。 MapsId 甚至只是与 Id 注释建立关系让 JPA 为您处理分配这样的派生 Id。
-
谢谢。
Foo和Bar已经是现有对象,因此 ID 没有问题。由于密钥完全由关系组成,我可以在创建新对象时完全忽略密钥并设置mapsId字段? -
另外,如果我的复合键同时包含关系和普通列,那么它们将如何工作?我想我需要上面的键以及设置关系?
标签: jpa eclipselink