如何使用Hibernate映射组合键? [英] How to map a composite key with Hibernate?
问题描述
创建表时间(
levelStation int(15)非空,
src varchar(100)非空,
dst varchar(100)非空,
距离int(15)不是(15)非空,
confPathID int(15)非空,
约束ConfPath_fk外键(confPathID)引用ConfPath(confPathID),
主键levelStation,confPathID)
)ENGINE = InnoDB DEFAULT CHARSET = utf8;
要映射组合键,可以使用 EmbeddedId
或 IdClass
注释。我知道这个问题不是严格的JPA,但规范定义的规则也适用。因此,它们是:
lockquote
2.1.4主键和实体标识
...
复合主键必须
对应于单个
持久字段或属性或
这样的集合字段或属性为
,如下所述。主键类
必须定义为表示
复合主键。当
数据库键由多个
列组成时,复合
主键通常在从旧数据库映射
时出现。 EmbeddedId
和
IdClass
注释用于
表示复合主键。 见
第9.1.14和9.1.15节。
...
以下规则适用于
复合主键:
- 主键类必须是公共的,并且必须有一个公共无参数
构造函数 - 如果使用基于属性的访问,主键
的属性必须是public或protected。 - 主键类必须是
serializable
。 - 主键类
必须定义等于
和hashCode
方法。这些方法的值
相等的语义必须是
与
键映射到的数据库类型的数据库相等
一致。 - 复合主键必须e ither被表示和映射为一个
嵌入类(参见9.1.14节,
EmbeddedId Annotation),或者必须是
表示并映射到多个
字段或属性实体
类(见第9.1.15节IdClass
注释)。
- 如果复合主键类映射到多个字段或
实体类的属性,主键类的
名称或主键类
中的
属性,以及实体类中的
属性必须是
对应,并且它们的类型必须是$
- 从物理模型的角度来看,没有区别
-
@EmbeddedId
莫名其妙更清楚地表明,关键是一个复合关键字,当组合关键字pk是一个有意义的实体本身或它在代码中重用时,它是有意义的 。
- code> @IdClass
使用 IdClass $ c $
组合主键的类可能看起来像(可能是一个静态内部类):
public class TimePK实现Serializable {
protected Integer levelStation;
保护整数confPathID;
public TimePK(){}
public TimePK(Integer levelStation,Integer confPathID){
this.levelStation = levelStation;
this.confPathID = confPathID;
}
// equals,hashCode
}
实体:
$ $ p $ @Entity
@IdClass(TimePK.class)
类实现Serializable的时间{
@Id
私人整数levelStation;
@Id
私人整数confPathID;
private String src;
private String dst;
私人整数距离;
私人整数价格;
// getters,setters
}
IdClass
注释将多个字段映射到表PK。
With EmbeddedId
主键可能看起来像(可能是一个静态内部类):
@Embeddable
public class TimePK implements Serializable {
保护整数levelStation;
保护整数confPathID;
public TimePK(){}
public TimePK(Integer levelStation,Integer confPathID){
this.levelStation = levelStation;
this.confPathID = confPathID;
}
// equals,hashCode
}
实体:
$ b $ pre $ @Entity
类实现可序列化的时间{
@EmbeddedId
private TimePK timePK ;
private String src;
private String dst;
私人整数距离;
私人整数价格;
// ...
}
@EmbeddedId
注解将一个PK类映射到表PK。
差异:
用于指定某些字段组合是唯一的,但这些字段没有特殊含义。
组合主键的类可能看起来像(可能是一个静态内部类):
public class TimePK实现Serializable {
protected Integer levelStation;
保护整数confPathID;
public TimePK(){}
public TimePK(Integer levelStation,Integer confPathID){
this.levelStation = levelStation;
this.confPathID = confPathID;
}
// equals,hashCode
}
实体:
$ $ p $ @Entity
@IdClass(TimePK.class)
类实现Serializable的时间{
@Id
私人整数levelStation;
@Id
私人整数confPathID;
private String src;
private String dst;
私人整数距离;
私人整数价格;
// getters,setters
}
IdClass
注释将多个字段映射到表PK。
With EmbeddedId
主键可能看起来像(可能是一个静态内部类):
@Embeddable
public class TimePK implements Serializable {
保护整数levelStation;
保护整数confPathID;
public TimePK(){}
public TimePK(Integer levelStation,Integer confPathID){
this.levelStation = levelStation;
this.confPathID = confPathID;
}
// equals,hashCode
}
实体:
$ b $ pre $ @Entity
类实现可序列化的时间{
@EmbeddedId
private TimePK timePK ;
private String src;
private String dst;
私人整数距离;
私人整数价格;
// ...
}
@EmbeddedId
注解将一个PK类映射到表PK。
差异:
它们也影响您编写查询的方式(使它们或多或少冗长): 与 with
IdClass
select t.levelStation from时间t
EmbeddedId
选择时间t.timePK.levelStation t
参考文献
In this code, how to generate a Java class for the composite key (how to composite key in hibernate):
create table Time (
levelStation int(15) not null,
src varchar(100) not null,
dst varchar(100) not null,
distance int(15) not null,
price int(15) not null,
confPathID int(15) not null,
constraint ConfPath_fk foreign key(confPathID) references ConfPath(confPathID),
primary key (levelStation, confPathID)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
To map a composite key, you can use the EmbeddedId
or the IdClass
annotations. I know this question is not strictly about JPA but the rules defined by the specification also applies. So here they are:
2.1.4 Primary Keys and Entity Identity
...
A composite primary key must correspond to either a single persistent field or property or to a set of such fields or properties as described below. A primary key class must be defined to represent a composite primary key. Composite primary keys typically arise when mapping from legacy databases when the database key is comprised of several columns. The
EmbeddedId
andIdClass
annotations are used to denote composite primary keys. See sections 9.1.14 and 9.1.15....
The following rules apply for composite primary keys:
- The primary key class must be public and must have a public no-arg constructor.
- If property-based access is used, the properties of the primary key class must be public or protected.
- The primary key class must be
serializable
.- The primary key class must define
equals
andhashCode
methods. The semantics of value equality for these methods must be consistent with the database equality for the database types to which the key is mapped.- A composite primary key must either be represented and mapped as an embeddable class (see Section 9.1.14, "EmbeddedId Annotation") or must be represented and mapped to multiple fields or properties of the entity class (see Section 9.1.15, "IdClass Annotation").
- If the composite primary key class is mapped to multiple fields or properties of the entity class, the names of primary key fields or properties in the primary key class and those of the entity class must correspond and their types must be the same.
With an IdClass
The class for the composite primary key could look like (could be a static inner class):
public class TimePK implements Serializable {
protected Integer levelStation;
protected Integer confPathID;
public TimePK() {}
public TimePK(Integer levelStation, Integer confPathID) {
this.levelStation = levelStation;
this.confPathID = confPathID;
}
// equals, hashCode
}
And the entity:
@Entity
@IdClass(TimePK.class)
class Time implements Serializable {
@Id
private Integer levelStation;
@Id
private Integer confPathID;
private String src;
private String dst;
private Integer distance;
private Integer price;
// getters, setters
}
The IdClass
annotation maps multiple fields to the table PK.
With EmbeddedId
The class for the composite primary key could look like (could be a static inner class):
@Embeddable
public class TimePK implements Serializable {
protected Integer levelStation;
protected Integer confPathID;
public TimePK() {}
public TimePK(Integer levelStation, Integer confPathID) {
this.levelStation = levelStation;
this.confPathID = confPathID;
}
// equals, hashCode
}
And the entity:
@Entity
class Time implements Serializable {
@EmbeddedId
private TimePK timePK;
private String src;
private String dst;
private Integer distance;
private Integer price;
//...
}
The @EmbeddedId
annotation maps a PK class to table PK.
Differences:
- From the physical model point of view, there are no differences
@EmbeddedId
somehow communicates more clearly that the key is a composite key and IMO makes sense when the combined pk is either a meaningful entity itself or it reused in your code.@IdClass
is useful to specify that some combination of fields is unique but these do not have a special meaning.
They also affect the way you write queries (making them more or less verbose):
with
IdClass
select t.levelStation from Time t
with
EmbeddedId
select t.timePK.levelStation from Time t
References
- JPA 1.0 specification
- Section 2.1.4 "Primary Keys and Entity Identity"
- Section 9.1.14 "EmbeddedId Annotation"
- Section 9.1.15 "IdClass Annotation"
这篇关于如何使用Hibernate映射组合键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!