在hibernate中添加共享主键和主键

时间:2018-05-16 02:42:34

标签: java hibernate jpa

我有两张名为Invoice and Delivery

的表

发票

invoiceId(PK)

投放

deliveryId(PK)
invoice_invoiceId(PK,FK)

这些是我用java编写的类

发票=>

@Entity(name = "invoice")
public class Invoice {
    @Id      
    @OneToOne(fetch =FetchType.LAZY,cascade = CascadeType.ALL,mappedBy = "invoice")
    private Delivery delivery;
}

和与之相关的getter setters

投放=>

public class Delivery{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int deliveryId;

    @OneToOne
    @MapsId
    @Id
    @JoinColumn(name = "invoice_invoiceId",unique = true)
    private Invoice invoice;
}

这会在我创建会话工厂的地方抛出一个 java.lang.NullPointerException ,因为我在Delivery类中包含了2个@Id注释。

我的问题是如何在同一个表格中将deliveryId作为PK和发票(invoice_invoiceId)作为共享主键?

2 个答案:

答案 0 :(得分:0)

这似乎是一个衍生的身份&#34 ;;但让invoice_invoiceId成为Delivery主键的一部分似乎有点奇怪......也许你可以尝试这样的事情:

@IdClass这样的需求添加Delivery

public class DeliveryId implements Serializable {
    private int deliveryId; // matches the name of the attribute
    private int invoice;  // matches name of attribute and type of User PK
    ...
}

然后像这样指定Delivery' @IdClass

@Entity
@IdClass(DeliveryId.class)
public class Delivery {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int deliveryId;

    @Id
    @OneToOne
    @JoinColumn(name = "invoice_invoiceId", unique = true)
    private Invoice invoice;
}

并且Invoice.delivery需要指定@MapsId注释:

@Entity
public class Invoice {
    @Id
    private int invoiceId;

    @MapsId
    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "invoice")
    private Delivery delivery;
}

在第2.4.1节的JPA 2.1规范中讨论了衍生身份(带有示例)。

答案 1 :(得分:0)

我通过使用复合键

解决了这个问题

这是我的复合键类=>

@Embeddable
public class CompositeId implements Serializable{
    @Column(unique = true)
    private int deliveryId;
    @MapsId
    @OneToOne
    @JoinColumn(name = "invoiceId",unique = true)
    private Invoice invoiceId;
    //hashcode and equals methods
}

发票类=>

@Entity
public class Invoice {
    @Id
    private int invoiceId;
    @OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY,mappedBy = "compositeId.invoiceId")
    private Delivery deliveryId;
}

投放类=>

@Entity
public class Delivery {
    @EmbeddedId
    private CompositeId compositeId;
}

因此,交付表将拥有自己的PK和invoiceId作为共享PK

假设我们正在向此Delivery表添加另一个共享pk。所以我们需要将它添加到CompositeId类。

希望这会有所帮助。 :)