JPA复合主键

时间:2011-06-23 07:35:26

标签: java sql-server hibernate jpa maven-2

我的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 is generated from the classes时,相应表的主键由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)

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

2 个答案:

答案 0 :(得分:4)

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

Mapping ManyToMany with composite Primary key and Annotation:

答案 1 :(得分:0)

由于您使用的是@IdClass,因此PricePK类不需要使用@Embeddable 注释进行标记。 http://www.java2s.com/Code/Java/JPA/SetIdClassforCompoundKey.htm

中给出了一个示例

我尝试删除@Embeddable类上的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;
}