11

我在问并回答我自己的问题,但我并不认为我有最好的答案。如果你有更好的,请发布!

相关问题:

我有一对具有简单聚合关系的类:一个的任何实例都拥有另一个的一些实例。拥有的类有自己的某种主键,并且拥有的类通过相应的外键与这个类具有多对一的关系。我希望拥有的类有一个包含该外键和一些附加信息的主键。

为了争论,让我们使用那些常年最喜欢的,Order 和 OrderLine。

SQL 看起来像这样:

-- 'order' may have been a poor choice of name, given that it's an SQL keyword!
create table Order_ (
    orderId integer primary key
);
create table OrderLine (
    orderId integer not null references Order_,
    lineNo integer not null,
    primary key (orderId, lineNo)
);

我想使用 JPA 将其映射到 Java 中。Order 是微不足道的,OrderLine 可以用@IdClass 处理。这是代码- 代码是相当传统的,我希望你能原谅我的特质。

但是,使用@IdClass 涉及编写一个复制OrderLine 中的字段的ID 类。我想避免这种重复,所以我想改用@EmbeddedId。

但是,这样做的天真尝试失败了:

@Embeddable
public class OrderLineKey {
    @ManyToOne
    private Order order;
    private int lineNo;
}

OpenJPA 拒绝将其用作@EmbeddedId。我没有尝试过其他提供者,但我不希望他们成功,因为 JPA 规范要求组成 ID 类的字段是基本的,而不是关系。

那么,我能做什么?我如何编写一个其键包含@ManyToOne 关系但作为@EmbeddedId 处理的类?

4

1 回答 1

19

我不知道不涉及复制任何字段的方法(对不起!)。但它可以以直接和标准的方式完成,只涉及复制关系字段。关键是 JPA 2 中引入的@MapsId注解。

可嵌入键类如下所示:

@Embeddable
public class OrderLineKey {
    private int orderId;
    private int lineNo;
}

嵌入实体类如下所示:

@Entity
public class OrderLine{
    @EmbeddedId
    private OrderLineKey id;

    @ManyToOne
    @MapsId("orderId")
    private Order order;
}

@MapsId 注释声明应用它的关系字段有效地重新映射嵌入 ID 中的基本字段。

这是 OrderId 的代码

于 2011-08-25T19:37:06.727 回答