Java 仅使用ID字段为联接表创建JPA注释实体

Java 仅使用ID字段为联接表创建JPA注释实体,java,sql,jpa,Java,Sql,Jpa,我试图找出一种更干净的方法,只使用两个联接表的实体id将联接表保存回数据库。我可以让我的代码按原样工作,但我觉得应该有一种更干净的方式 假设我有一个实体,它表示一个简单的sql联接表,如下所示: @Entity @Table(name = "FOOBAR") public class FooBar{ @ManyToOne(fetch = FetchType.Lazy) @JoinColumn(name = "FOO_ID) public Foo foo; @M

我试图找出一种更干净的方法,只使用两个联接表的实体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对象传递给我的save方法以保存连接

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

然而,这很愚蠢,我的联接表只需要foo和bar id,而不是完整的DB对象。我已经有了我所需要的一切,而不用去打DB去拿食物和酒吧

事实上,我可以简单地使用它们的公共ID构造一个Foo对象和bar对象,忽略对象的所有其他字段,从这两个“空”Foo和bar对象创建一个FooBar对象,并将其传递到save,这样就可以在没有额外DB点击的情况下正常工作

然而,不知何故,这样做感觉有点不干净。我用这种方法创建了两个“虚拟”对象。我的foo和bar对象可能有一些nullable=false列,我的DB contract承诺这些列永远不会为null,因此构造一个foo对象来为这些列提供null字段感觉是错误的;就好像我在破坏这些物品的合同。我不希望任何一个对象的构造函数只接受一个ID,因为;我想强迫他们以一种在任何时候有人建造他们时都遵守我合同的方式来建造他们。我宁愿不要故意创造违背我承诺的东西

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


我是否可以创建一个只有ID的FooBar对象,并将该对象绑定到DB,这样如果调用getter就像从DB获得FooBar一样,它就会延迟加载Foo和Bar对象?

这似乎就是您要寻找的。它创建并返回一个对象,该对象可以在任何需要实体引用的地方使用,并且可以(但在您的情况下,不必)延迟获取其所有状态

为联接表创建一个类是过分的

JPA有注释,它为您创建了关系

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

在本例中,我将选择
Foo
作为关系的所有者

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

@ManyToMany
@JoinTable(name="FOOBAR", joinColumns=@JoinColumn(name="FOO_ID"),
    inverseJoinColumns=@JoinColumn(name="BAR_ID"))
public Set<Bar> bars;
注意,虽然我使用了
Set
,但您可以使用
List


注意:
manytomy
默认情况下是惰性的。。。我建议还是这样吧。

谢谢,如果我对你说实话的话,这是一个很好的答案:)事实上,这个表是用来做更多的连接,我认为我们有很好的理由。我过分简化了这一部分,以表达我认为的问题:)尽管如此,我感谢你的回答,因为这是一个很好的回答,因为我问了这个问题;这是我所缺乏的提问能力:)虽然
List
被认为性能更好,但我知道Hibernate建议使用
Set
以获得最大的正确性。当存在真正链接到关系的其他状态时,通常会使用实体映射联接表,而不是任何一个相关实体(想想员工和公司实体的招聘日期)。我希望OP能这样使用它,所以我没有提到@ManyToMany映射:)
@ManyToMany(mappedBy="bars")
public Set<Foo> foos;