如何在JPA中正确关联具有多个键的表

时间:2018-08-13 19:08:21

标签: java jpa one-to-many

我正在寻找一种方法来关联具有一对多关系的多个键的两个表。我有以下实体,也许这是一个设计不良的示例,但尽管如此:

项目

@Id
@Column(name = "item_id", columnDefinition = "INT(11)")
private Long itemId;

@Id
@Column(name = "name", columnDefinition = "VARCHAR(50)")
private String name;

@Column(name = "price", columnDefinition = "DECIMAL(12, 2)")
private Double price;

订购

@Id
@Column(name = "order_id", columnDefinition = "INT(11)")
private Long orderId;

@Id
@Column(name = "order_number", columnDefinition = "INT(11)")
private Long orderNumber;


@Column(name = "date", columnDefinition = "DATE")
private Date date;

@Column(name = "item_count", columnDefinition = "INT(11)")
private Long itemCount;

我需要在这些实体之间建立一对多关系,以便订单包含多个项目。

我的要求是最终的Orders表结构包含以下字段:

order_id,
order_number,
date,
item_count,
item_id

要使商品(单侧)与订单(多侧)相关联,我必须执行以下操作

项目

@OneToMany(fetch = FetchType.LAZY, mappedBy="item")
private List<Order> orders = new ArrayList<Order>();

订购

@ManyToOne
@JoinColumns({
    @JoinColumn(name = "item_id"),
    @JoinColumn(name = "name")
})
private Item item;

这可以编译,但是现在我的“订单”表包含一个名为“名称”的字段,我试图避免该字段。我如何仅通过item_id而不是item_id +名称关联表?

1 个答案:

答案 0 :(得分:1)

我会向您推荐几件事:

使用代理密钥

每个实体应仅具有一个@Id注释。 即使您的域具有自然的复合密钥,也请使用生成的(代理)密钥。

除了广泛使用的模式外,它还解决item_id + name关系的问题

避免双向映射

双向映射极大地增加了代码复杂性并降低了可维护性。而且,几乎在所有情况下都不需要它,并且可以轻松删除它。

避免延迟加载

如果您只需要加载Orders而没有Items,则使它们独立而不会出现任何延迟(不要使用@OneToMany映射)。

如果在大多数情况下将它们一起使用-请尽快加载项目。

这样做可以避免“ SessionClosedException”尝试调用普通的POJO getter。