gpt4 book ai didi

java - 仅使用 ID 字段为连接表创建 JPA 带注释的实体

转载 作者:行者123 更新时间:2023-11-30 03:17:51 25 4
gpt4 key购买 nike

我正在尝试找出一种更简洁的方法,仅使用两个连接表的实体 ID 将连接表保存回数据库。我可以让我的代码按原样工作,但我觉得应该有一种更简洁的方式。

假设我有一个代表简单 sql 连接表的实体,如下所示:

@Entity
@Table(name = "FOOBAR")
public class FooBar{

@ManyToOne(fetch = FetchType.Lazy)
@JoinColumn(name = "FOO_ID)
public Foo foo;

@ManyToOne(fetch = FetchType.Lazy)
@JoinColumn(name = "BAR_ID)
public Bar bar;

public FooBar(Foo foo, Bar bar){
this.foo=foo;
this.bar=bar;
}
}

我有一个方法,它接受 Foo id 和 Bar id,并希望将 FooBar 对象传递给我的保存方法以保存连接。

简单的实现会查询数据库,根据 Foo 和 Bar 对象的 ID 查找它们,将它们传递给 FooBar 构造函数,然后将新的 FooBar 传递给 save 方法。

但是,这很愚蠢,我的连接表唯一需要的是 foo 和 bar id,而不是完整的数据库对象。我已经拥有了所需的一切,而无需访问数据库来获取 Foo 和 Bar。

事实上,我可以简单地使用公共(public) ID 构造一个 Foo 对象和 bar 对象,忽略对象的所有其他字段,从这两个“空”foo 和 bar 对象创建一个 FooBar 对象,并将其传递给 save并且无需额外的数据库命中即可正常工作。

但是,这样做感觉有点不干净。我用这种方式创建两个“虚拟”对象。我的 foo 和 bar 对象可能有一些 nullable = false 列,我的数据库合约 promise 这些列永远不会为 null,因此构建一个 确实 这些列具有 null 字段的 foo 对象感觉是错误的;就好像我违反了这些元素的契约(Contract)一样。我不想要任何只接受 ID 的对象的构造函数,因为;每当有人 build 它们时,我想强制它们以遵守我的契约(Contract)的方式 build 。我宁愿不必故意创建违反我 promise 的对象。

我想知道是否有一种方法可以通过 JPA 或一些我可以做的快速编写的抽象来仅使用 foo 和 bar id 以干净且可交流的方式构建我的 FooBar 对象, 违反任何 Foo/Bar 约束。毕竟,当我第一次获取 FooBar 对象时,Foo 和 Bar 都是延迟加载的,它真正包含的只是 foo 和 bar id,直到我调用 getter;所以我已经包含了与数据库中的 FooBar 对象一样多的信息。

我可以创建一个仅包含 ID 的 FooBar 对象,并将该对象绑定(bind)到数据库,这样,如果 getter 被调用,就像我从数据库获取的 FooBar 一样,它会延迟加载 Foo 和 Bar 对象吗?

最佳答案

为连接表创建一个类是多余的。

JPA 有ManyToMany注释,它会为您创建关系。

您基本上需要选择一个实体来“拥有”这种关系。这或多或少是哪个类定义了用于连接的表。

在本例中,我将选择 Foo 作为拥有该关系的人。

Foo 中,您可以执行以下操作:

@ManyToMany
@JoinTable(name="FOOBAR", joinColumns=@JoinColumn(name="FOO_ID"),
inverseJoinColumns=@JoinColumn(name="BAR_ID"))
public Set<Bar> bars;

并在栏中:

@ManyToMany(mappedBy="bars")
public Set<Foo> foos;

注意,虽然我使用了Set,但你可以使用List代替。

注意:ManyToMany 默认情况下是 Lazy...我建议保持这种方式。

关于java - 仅使用 ID 字段为连接表创建 JPA 带注释的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32125784/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com