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

Java 在hibernate中添加共享主键和主键,java,hibernate,jpa,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 = "in

我有两张名为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;
}
public class Delivery{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int deliveryId;

    @OneToOne
    @MapsId
    @Id
    @JoinColumn(name = "invoice_invoiceId",unique = true)
    private Invoice invoice;
}
@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;
}
以及与之相关的getters setters

交付=>

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

    @OneToOne
    @MapsId
    @Id
    @JoinColumn(name = "invoice_invoiceId",unique = true)
    private Invoice invoice;
}
@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;
}
这就抛出了一个java.lang.NullPointerException,在这里我创建了一个会话工厂,因为我在交付类中包含了2个@Id注释

我的问题是如何使deliveryId成为PK,并使invoice(invoice\u invoiceId)成为同一个表中的共享主键?

这似乎是一个“派生标识”;但是将
invoice\u invoiceId
作为
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
    ...
}
@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;
}
添加一个
@IdClass
用于
交付
需要如下:

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
    ...
}
@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;
}
然后指定
Delivery
@IdClass
如下:

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
    ...
}
@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;
}

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

我使用复合密钥解决了它

这是我的复合密钥类=>

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

    @OneToOne
    @MapsId
    @Id
    @JoinColumn(name = "invoice_invoiceId",unique = true)
    private Invoice invoice;
}
@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;
}
发票类别=>

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

    @OneToOne
    @MapsId
    @Id
    @JoinColumn(name = "invoice_invoiceId",unique = true)
    private Invoice invoice;
}
@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;
}
交付类别=>

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

    @OneToOne
    @MapsId
    @Id
    @JoinColumn(name = "invoice_invoiceId",unique = true)
    private Invoice invoice;
}
@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

假设我们正在将另一个共享pk添加到此传递表。所以我们也需要将其添加到CompositeId类中


希望这有帮助。:)

您是否尝试过
@EmbeddedId
IdClass