JPA复合主键

我的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; } 

我需要定义一个类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; } 

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

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

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

无法在表’PRICE’中的可空列上定义PRIMARY KEY约束

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

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

最近我使用Composite Primary key和annotation创建了ManyToMany关系作为双向@OneToMany 。 这段代码完美无瑕。 也许它会有所帮助:

使用复合主键和注释映射ManyToMany:

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

我尝试使用代码删除PricePK类上的PricePK ,以及在MYSQL数据库中生成的非空字段的价格表。

以下是如何使用@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; }