Java JPA复合主键

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6450780/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-16 06:03:37  来源:igfitidea点击:

JPA composite primary key

javasql-serverhibernatejpamaven-2

提问by Dónal

I have the following classes in my JPA model (getters, setters, and irrelevant fields omitted):

我的 JPA 模型中有以下类(省略了 getter、setter 和不相关的字段):

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Currency {

    @Id
    private Integer ix;
}

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Product {

    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
}

I need to define a class Price, such that when the DDL is generated from the classes, the primary key of the corresponding table is composed of the keys for Productand Currency. I've tried the following:

我需要定义一个类Price,使得当从所述类生成DDL时,相应的表的主键被由密钥ProductCurrency。我尝试了以下方法:

@Entity @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
@IdClass(PricePK.class)
public class Price {

    @Id @ManyToOne(optional = false)
    private Product product;

    @Id
    @ManyToOne(optional = false)
    private Currency currency;
}

@Embeddable
public class PricePK implements Serializable {

    Integer product;        
    Integer currency;
}

But this generates the following for the PRICEtable:

但这会为PRICE表生成以下内容:

create table PRICE (
    currency_id int null,
    product_id int null,
    primary key (currency_id, product_id)
);

Notice that both currency_idand product_idare nullable, which causes the following error when I try to load the DDL into SQL Server

请注意,currency_idproduct_id都可以为空,当我尝试将 DDL 加载到 SQL Server 时会导致以下错误

Cannot define PRIMARY KEY constraint on nullable column in table 'PRICE'

无法对表“PRICE”中的可为空列定义 PRIMARY KEY 约束

I don't understand why these are nullable, because in the domain model they are annotated @ManyToOne(optional = false)

我不明白为什么这些可以为空,因为在域模型中它们被注释 @ManyToOne(optional = false)

The DDL is generated using the org.hibernate.dialect.SQLServerDialectSQL dialect.

DDL 是使用org.hibernate.dialect.SQLServerDialectSQL 方言生成的。

采纳答案by danny.lesnik

Recently I created ManyToMany relation using Composite Primary key and annotation as bi directional @OneToMany. This code works flawless. Maybe it will help:

最近我使用复合主键和注释作为双向创建了 ManyToMany 关系@OneToMany。这段代码完美无缺。也许它会有所帮助:

Mapping ManyToMany with composite Primary key and Annotation:

使用复合主键和注释映射多对​​多:

回答by Dilini Rajapaksha

Since you are using @IdClass, the PricePKclass need not be marked with the @Embeddable annotation. An example is given in http://www.java2s.com/Code/Java/JPA/SetIdClassforCompoundKey.htm

由于您使用的是@IdClass,因此PricePK不需要用@Embeddable 注释标记该类。http://www.java2s.com/Code/Java/JPA/SetIdClassforCompoundKey.htm 中给出了一个示例

I tried your code removing the @Embeddableon PricePKclass, and the price table generated in MYSQL database with not null fields.

我试过你的代码删除了@EmbeddableonPricePK类,以及在 MYSQL 数据库中生成的带有非空字段的价格表。

Following is how you could use @EmbeddedIdto achieve the required result: (getters and setters omitted)

以下是您可以如何使用@EmbeddedId来实现所需的结果:(省略了 getter 和 setter)

@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Price {

    @EmbeddedId
    PricePK pricePk;
}

@Embeddable
public class PricePK implements Serializable {

    @ManyToOne(optional = false)
    private Product product;

    @ManyToOne(optional = false)
    private Currency currency;
}