在JPA中,有几种方法可以创建复合键字段。让我们看看使用
@Embeddable注释
的方法。
让我们从实体类开始。
@Entity
@Table
public class TraceRecord {
@Id
private TraceRecordPk id;
@Version
@Transient
private int version;
@Column(columnDefinition = "char")
private String durationOfCall;
@Column(columnDefinition = "char")
private String digitsDialed;
@Column(columnDefinition = "char")
private String prefixCalled;
@Column(columnDefinition = "char")
private String areaCodeCalled;
@Column(columnDefinition = "char")
private String numberCalled;
}
这是一个相当简单的实体类,其中包含@Id和@Version字段以及一些@Column定义。不详细介绍,您会发现@Version字段也被注释为@Transient。我之所以这样做,只是因为我的表也没有用于跟踪版本的列,但我的数据库已经记录了,所以我对版本控制并不太担心。您还会注意到@Column字段在columnDefinition属性上设置了“char”的值。这是因为我的表中的字段被定义为char而不是varchar。如果它们是varchar,我就不需要这样做,因为String默认映射到varchar字段。
@Id字段是我现在感兴趣的内容。它不是标准的Java类型,而是我自己定义的类。以下是该类。
@Embeddable
public class TraceRecordPk implements Serializable {
private static final long serialVersionUID = 1L;
@Temporal(TemporalType.DATE)
@Column
private Date dateOfCall;
@Column(columnDefinition="char")
private String timeOfCall;
@Column(columnDefinition="char")
private String callingParty;
public TraceRecordPk(Date dateOfCall, String timeOfCall, String callingParty) {
this.dateOfCall = dateOfCall;
this.timeOfCall = timeOfCall;
this.callingParty = callingParty;
}
}
为了使这个类能够成为实体类上的@Id字段,它需要像我之前提到的那样被注释为@Embeddable。我选择的三个字段只是普通的@Column定义。我没有为每个字段创建getter/setter,而是实现了一个构造函数,该构造函数接受所有3个字段的值,使任何实例都是不可变的。当用@Embeddable注释一个类时,该类将需要实现Serializable。因此,我添加了一个默认的serialVersionUID来适应。
现在你已经创建了一个带有@Embeddable注释的类,你可以将其作为实体类中@Id字段的类型使用。简单吧。