sak*_*ana 120 java annotations jpa java-persistence-api
的JPA(Java持久性API)规范有2名不同的方式来指定实体组合键:@IdClass和@EmbeddedId.
我在我的映射实体上使用了两个注释,但对于那些不熟悉的人来说,结果却是一团糟JPA.
我想只采用一种方法来指定复合键.哪一个真的最好?为什么?
Jor*_*ira 81
我认为这@EmbeddedId可能更冗长,因为@IdClass您无法使用任何字段访问运算符访问整个主键对象.使用@EmbeddedId你可以这样做:
@Embeddable class EmployeeId { name, dataOfBirth }
@Entity class Employee {
@EmbeddedId EmployeeId employeeId;
...
}
Run Code Online (Sandbox Code Playgroud)
这给出了构成组合键的字段的清晰概念,因为它们都是在通过字段访问操作符访问的类中聚合的.
与另一个不同之处@IdClass,并@EmbeddedId是当它涉及到写HQL:
随@IdClass你写:
select e.name from Employee e
和@EmbeddedId你一起写:
select e.employeeId.name from Employee e
您必须为同一查询编写更多文本.有些人可能会认为这与一种更自然的语言不同,例如推广的语言IdClass.但是大多数时候从查询中理解给定字段是复合键的一部分是非常宝贵的帮助.
laz*_*laz 17
我发现了一个必须使用EmbeddedId而不是IdClass的实例.在这种情况下,有一个连接表,其中定义了其他列.我尝试使用IdClass来解决此问题,以表示明确表示连接表中的行的实体的键.我无法以这种方式工作.值得庆幸的是"Java Persistence With Hibernate"有一节专门讨论这个主题.一个提议的解决方案与我的解决方案非常相似,但它使用的是EmbeddedId.我在书中的对象之后对我的对象进行了建模,现在它的行为正确.
Ade*_*lin 16
使用复合主键有三种策略:
@Embeddable并为您的实体类添加标准属性,标记为@Id.@EmbeddedId.@Id,并用@IdClass实际类标记,提供主键类的类.@Id标记为类的使用@Embeddable是最自然的方法.@Embeddable无论如何,该标记可用于非主键可嵌入值.它允许您将复合主键视为单个属性,并允许@Embeddable在其他表中重用该类.
下一个最自然的方法是使用@EmbeddedId标签.这里,主键类不能在其他表中使用,因为它不是@Embeddable实体,但它确实允许我们将键视为某个类的单个属性.
最后,使用@IdClass和@Id注释允许我们使用与主键类中的属性名称相对应的实体本身的属性来映射复合主键类.名称必须对应(没有覆盖它的机制),主键类必须履行与其他两种技术相同的义务.这种方法的唯一优点是它能够从封闭实体的接口"隐藏"主键类的使用.的@IdClass批注采用类类型的值参数,该参数必须是类被用作化合物主键.与要使用的主键类的属性对应的字段必须全部注释@Id.
参考:http://www.apress.com/us/book/9781430228509
Ond*_*zek 12
据我所知,如果你的复合PK包含FK,它使用起来更简单,更直接 @IdClass
随着@EmbeddedId你必须定义映射为您的FK列两次,onece在@Embeddedable一次用于为即@ManyToOne其中@ManyToOne已经被只读(@PrimaryKeyJoinColumn),因为你不能有一列两个变量(可能发生的冲突)设置.
所以你必须使用简单的类型来设置你的FK @Embeddedable.
在使用@IdClass这种情况的另一个站点上可以更容易地处理,如主键通过OneToOne和ManyToOne关系所示:
示例JPA 2.0 ManyToOne id注释
...
@Entity
@IdClass(PhonePK.class)
public class Phone {
@Id
private String type;
@ManyToOne
@Id
@JoinColumn(name="OWNER_ID", referencedColumnName="EMP_ID")
private Employee owner;
...
}
Run Code Online (Sandbox Code Playgroud)
示例JPA 2.0 id类
...
public class PhonePK {
private String type;
private long owner;
public PhonePK() {}
public PhonePK(String type, long owner) {
this.type = type;
this.owner = owner;
}
public boolean equals(Object object) {
if (object instanceof PhonePK) {
PhonePK pk = (PhonePK)object;
return type.equals(pk.type) && owner == pk.owner;
} else {
return false;
}
}
public int hashCode() {
return type.hashCode() + owner;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
76160 次 |
| 最近记录: |