如何在JPA中创建包含@ManyToOne属性作为@EmbeddedId的复合主键? [英] How to create a composite primary key which contains a @ManyToOne attribute as an @EmbeddedId in JPA?

查看:331
本文介绍了如何在JPA中创建包含@ManyToOne属性作为@EmbeddedId的复合主键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在询问并回答我自己的问题,但我不认为我的回答是最好的.如果您有更好的选择,请发布!

I'm asking and answering my own question, but i'm not assuming i have the best answer. If you have a better one, please post it!

相关问题:

  • How to set a backreference from an @EmbeddedId in JPA
  • hibernate mapping where embeddedid (?)
  • JPA Compound key with @EmbeddedId

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

I have a pair of classes which are in a simple aggregation relationship: any instance of one owns some number of instances of the other. The owning class has some sort of primary key of its own, and the owned class has a many-to-one to this class via a corresponding foreign key. I would like the owned class to have a primary key comprising that foreign key plus some additional information.

为了争辩,让我们使用那些常年使用的收藏夹Order和OrderLine.

For the sake of argument, let's use those perennial favourites, Order and OrderLine.

SQL看起来像这样:

The SQL looks something like this:

-- '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中.订单微不足道,可以使用@IdClass处理OrderLine. 这是该代码-该代码相当传统,我希望您能原谅我的特质.

I would like to map this into Java using JPA. Order is trivial, and OrderLine can be handled with an @IdClass. Here's the code for that - the code is fairly conventional, and i hope you'll forgive my idiosyncrasies.

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

However, using @IdClass involves writing an ID class which duplicates the fields in the OrderLine. I would like to avoid that duplication, so i would like to use @EmbeddedId instead.

但是,天真的尝试失败:

However, a naive attempt to do this fails:

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

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

OpenJPA rejects the use of that as an @EmbeddedId. I haven't tried other providers, but i wouldn't expect them to succeed, because the JPA specification requires that the fields making up an ID class be basic, not relationships.

那我该怎么办?我该如何编写一个其键包含@ManyToOne关系但作为@EmbeddedId处理的类?

So, what can i do? How can i write a class whose key contains @ManyToOne relationship, but is handled as an @EmbeddedId?

推荐答案

我不知道一种不涉及重复任何字段的方法(抱歉!).但这可以通过直接复制关系字段的简单而标准的方式来完成.关键是JPA 2中引入的 @MapsId 批注.

I don't know of a way to do this which doesn't involve duplicating any fields (sorry!). But it can be done in a straightforward and standard way that involves duplicating only the relationship fields. The key is the @MapsId annotation introduced in JPA 2.

可嵌入的密钥类如下:

@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重新映射了一个基本字段.

The @MapsId annotation declares that the relationship field to which it is applied effectively re-maps a basic field from the embedded ID.

这是OrderId的代码.

这篇关于如何在JPA中创建包含@ManyToOne属性作为@EmbeddedId的复合主键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆