Java Hibernate组合实体

Java Hibernate组合实体,java,hibernate,jpa,jpa-2.1,Java,Hibernate,Jpa,Jpa 2.1,我可能混淆了术语,但我称之为简单实体的东西类似于客户或产品,也就是说,一个有自己身份的东西,我使用的是整数id 组合实体类似于CustomerProduct,允许创建m:n映射并将一些数据与之关联。我创造 class CustomerProduct extends MyCompositeEntity { @Id @ManyToOne private Customer; @Id @ManyToOne private Product; private String someS

我可能混淆了术语,但我称之为简单实体的东西类似于
客户
产品
,也就是说,一个有自己身份的东西,我使用的是
整数id

组合实体类似于
CustomerProduct
,允许创建m:n映射并将一些数据与之关联。我创造

class CustomerProduct extends MyCompositeEntity {
    @Id @ManyToOne private Customer;
    @Id @ManyToOne private Product;
    private String someString;
    private int someInt;
}
我明白了

复合id类必须实现可序列化

这让我直接找到了这些。我可以实现
可序列化
,但这意味着将
客户
产品
序列化为
客户产品
的一部分,这对我来说毫无意义。我需要的是一个包含两个
Integer
s的复合键,就像普通键只有一个
Integer

我偏离轨道了吗


如果没有,我如何仅使用注释(和/或代码)来指定它?

Hibernate会话对象需要可序列化,这意味着所有引用的对象也必须可序列化。即使将基元类型用作复合键,也需要添加序列化步骤

您可以在Hibernate中将复合主键与注释
@EmbeddedId
@IdClass
一起使用

使用
IdClass
可以执行以下操作(假设您的实体使用整数键):

您的主键类必须是公共的,并且必须有一个公共的无参数构造函数。它还必须是可序列化的

您还可以使用
@EmbeddedId
@embeddedable
,这更清楚一些,允许您在其他地方重用PK

@Embeddable
public class CustomerProduckKey implements Serializable {
    private int customerId;
    private int productId;
    //...
}

@Entity
class CustomerProduct extends MyCompositeEntity {
    @EmbeddedId CustomerProduckKey customerProductKey;

    private String someString;
    private int someInt;
}
您可以使用和:

@Embeddable
public class CustomerProduckKey implements Serializable {
    private int customerId;
    private int productId;
    //...
}

@Entity
class CustomerProduct extends MyCompositeEntity {
    @EmbeddedId CustomerProduckKey customerProductKey;

    private String someString;
    private int someInt;
}
@Embeddable
public class CustomerProductPK implements Serializable {
    private Integer customerId;
    private Integer productId;
    //...
}

@Entity
class CustomerProduct {
    @EmbeddedId
    CustomerProductPK customerProductPK;

    @MapsId("customerId")
    @ManyToOne
    private Customer;

    @MapsId("productId")
    @ManyToOne
    private Product;

    private String someString;
    private int someInt;
}