Hibernate 无主键表(复合主键)映射(一)

2014-11-24 09:10:00 · 作者: · 浏览: 4

1. 为什么要有复合主键映射
在现实中我们可能会遇到许多表可能是没有主键的,那么我们对其做映射后使用会是什么样的结果?能正常得到我们想要的吗?结果应该是得不到想要的结果,而得到的可能会是如下的报错:

Caused by:org.hibernate.AnnotationException: No identifier specified for entity: xxx.xxx.xxx

这个结果告诉我们:Hibernate映射表是需要主键的。

所以复合主键映射就应运而生了。

2. 注意点
复合主键使用一个可嵌入的类作为主键表示,因此你需要使用@Id和@Embeddable两个注解.还有一种方式是使用@EmbeddedId注解.当然还有一种方法那就是——使用@IdClass注解。具体请查看【hibernate-annotations-3.4.0.GA 2.2.6.映射复合主键与外键】。

当然,只需要选择其中的一种就可以了。^_^

注意所依赖的类必须实现 serializable以及实现equals()/hashCode()方法.

举一个具体事例:

2.1. User.java
[java]
package com.sourcefour.bean;
// default package
import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
/**
* User entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table (name="t_user_composite_pk"
)
public class User implements java.io.Serializable {
// Fields
private UserId id;
// Constructors
/** default constructor */
public User() {
}
/** full constructor */
public User(UserId id) {
this.id = id;
}
// Property accessors
@EmbeddedId
@AttributeOverrides( {
@AttributeOverride(name="intId", column=@Column (name="intId", nullable=false) ),
@AttributeOverride(name="varcName", column=@Column (name="varcName", length=50) ),
@AttributeOverride(name="varcAddress", column=@Column (name="varcAddress", length=50) ),
@AttributeOverride(name="intAge", column=@Column (name="intAge", nullable=false) ) } )
public UserId getId() {
return this.id;
}
public void setId(UserId id) {
this.id = id;
}
}

package com.sourcefour.bean;
// default package

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;


/**
* User entity. @author MyEclipse Persistence Tools
*/
@Entity
@Table(name="t_user_composite_pk"
)

public class User implements java.io.Serializable {


// Fields

private UserId id;


// Constructors

/** default constructor */
public User() {
}


/** full constructor */
public User(UserId id) {
this.id = id;
}


// Property accessors
@EmbeddedId

@AttributeOverrides( {
@AttributeOverride(name="intId", column=@Column(name="intId", nullable=false) ),
@AttributeOverride(name="varcName", column=@Column(name="varcName", length=50) ),
@AttributeOverride(name="varcAddress", column=@Column(name="varcAddress", length=50) ),
@AttributeOverride(name="intAge", column=@Column(name="intAge", nullable=false) ) } )

public UserId getId() {
return this.id;
}

public void setId(UserId id) {
this.id = id;
}
}
2.2. UserId.java

[java]
package com.sourcefour.bean;
// default package
import javax.persistence.Column;
import javax.persistence.Embeddable;
/**
* UserId entity. @author MyEclipse Persistence Tools
*/
@Embeddable
public class UserId implements java.io.Serializable {
// Fields
private int intId;
private String varcName;
private String varcAddress;
private int intAge;
// Constructors
/** default constructor */
public UserId() {
}
/** minimal constructor */
public UserId(int intId, int intAge) {
this.intId = intId;
this.intAge = intAge;
}
/** full constructor */
public UserId(int intId, String varcName, String varcAddress, int intAge) {
this.intId = intI