`

hibernate注解配置联合主键

阅读更多
有时一个实体的主键可能同时为多个,例如下面使用的字典“Dictionary”实体,需要通过dictId 、dictTypeid 和cityId 来查找指定实体,当且仅当dictId 、dictTypeid 和cityId 的值完全相同时,才认为是相同的实体对象。要配置这样的联合主键,步骤如以下所示。

(1)编写一个联合主键的类DictionaryPK,代码如下。

import java.io.Serializable;

import javax.persistence.Column;

/**
 * 字典表主键类(联合主键)
 * 
 * @author ahomeeye
 */
public class DictionaryPK implements Serializable {

	private static final long serialVersionUID = -1118337265519377063L;
	private String dictId; // 数据标识
	private String dictTypeid;// 数据类型标识
	private String cityId;// 所属本地网 默认0

	@Column(name = "DICT_ID")
	public String getDictId() {
		return dictId;
	}

	public void setDictId(String dictId) {
		this.dictId = dictId;
	}

	@Column(name = "DICT_TYPEID")
	public String getDictTypeid() {
		return dictTypeid;
	}

	public void setDictTypeid(String dictTypeid) {
		this.dictTypeid = dictTypeid;
	}

	@Column(name = "CITY_ID")
	public String getCityId() {
		return cityId;
	}

	public void setCityId(String cityId) {
		this.cityId = cityId;
	}

	public int hashCode() {
		final int PRIME = 31;
		int result = 1;
		result = PRIME * result + ((dictId == null) ? 0 : dictId.hashCode());
		result = PRIME * result
				+ ((dictTypeid == null) ? 0 : dictTypeid.hashCode());
		result = PRIME * result + ((cityId == null) ? 0 : cityId.hashCode());
		return result;
	}

	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;

		final DictionaryPK other = (DictionaryPK) obj;
		if (dictId == null) {
			if (other.dictId != null)
				return false;
		} else if (!dictId.equals(other.dictId))
			return false;

		if (dictTypeid == null) {
			if (other.dictTypeid != null)
				return false;
		} else if (!dictTypeid.equals(other.dictTypeid))
			return false;

		if (cityId == null) {
			if (other.cityId != null)
				return false;
		} else if (!cityId.equals(other.cityId))
			return false;

		return true;
	}

}


作为符合主键类,要满足以下几点要求:
1.必须实现Serializable接口。
2.必须有默认的public无参数的构造方法。
3.必须覆盖equals和hashCode方法。equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时,是根据equals的返回值来判断的。本例中,只有对象的dictId 、dictTypeid 和cityId 值完全相同时或同一个对象时则返回true,否则返回false。hashCode方法返回当前对象的哈希码,生成的hashCode相同的概率越小越好,算法可以进行优化。

(2)通过@IdClass注释在实体中标注联合主键,实体代码如下。
import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;

/**
 * 系统字典数据
 * 
 * @author ahomeeye
 */
@Entity
@Table(name = "T_DICT")
@IdClass(DictionaryPK.class)
public class Dictionary implements Serializable {

	private static final long serialVersionUID = 1L;
	private String dictId; // 数据标识
	private String dictTypeid;// 数据类型标识
	private String dictName;// 数据名称
	private String dictStatus;// 数据状态
	private String dictDesc;// 数据描述
	private Integer dictOrder;// 序号
	private String cityId;// 所属本地网 默认0

	@Id
	@Column(name = "DICT_ID")
	public String getDictId() {
		return dictId;
	}

	public void setDictId(String dictId) {
		this.dictId = dictId;
	}

	@Id
	@Column(name = "DICT_TYPEID")
	public String getDictTypeid() {
		return dictTypeid;
	}

	public void setDictTypeid(String dictTypeid) {
		this.dictTypeid = dictTypeid;
	}

	@Column(name = "DICT_NAME")
	public String getDictName() {
		return dictName;
	}

	public void setDictName(String dictName) {
		this.dictName = dictName;
	}

	@Column(name = "DICT_STATUS")
	public String getDictStatus() {
		return dictStatus;
	}

	public void setDictStatus(String dictStatus) {
		this.dictStatus = dictStatus;
	}

	@Column(name = "DICT_DESC")
	public String getDictDesc() {
		return dictDesc;
	}

	public void setDictDesc(String dictDesc) {
		this.dictDesc = dictDesc;
	}

	@Column(name = "DICT_INDEX")
	public Integer getDictOrder() {
		return dictOrder;
	}

	public void setDictOrder(Integer dictOrder) {
		this.dictOrder = dictOrder;
	}

	@Id
	@Column(name = "CITY_ID")
	public String getCityId() {
		return cityId;
	}

	public void setCityId(String cityId) {
		this.cityId = cityId;
	}

}


标注联合主键时需要注意以下几个问题。

1.@IdClass标注用于标注实体所使用主键规则的类。它的定义如下所示。

@Target({TYPE}) @Retention(RUNTIME)

public @interface IdClass {

Class value();

}

2.属性Class表示联合主键所使用的类,本例中使用DictionaryPK 这个联合主键类。

3.在实体中同时标注主键的属性。本例中在dictId、dictTypeid 和cityId 的getter方法前标注@Id,表示联合主键使用这两个属性。

(3)这样定义实体的联合主键后,通过以下代码便可以获得指定的实体对象:
DictionaryPK cpk = new DictionaryPK ("asyncTree","OperLogFunc","0");
Dictionary instance = entityManager.find(DictionaryPK .class, cpk);


参考:
http://www.blogjava.net/relax/archive/2009/09/18/295587.html


分享到:
评论

相关推荐

    Hibernate注解

    * @GenericGenerator —— 注解声明了一个hibernate的主键生成策略。支持十三种策略。该注解有如下属性 * name 指定生成器名称 * strategy 指定具体生成器的类名(指定生成策略)。 * parameters 得到strategy指定的...

    hibernate 体系结构与配置 参考文档(html)

    Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. 映射Person类 1.3.2. 单向Set-based的关联 1.3.3. 使关联工作 1.3.4. 值类型的集合 1.3.5...

    Hibernate实战(第2版 中文高清版)

     2.1.3 Hibernate配置和启动   2.1.4 运行和测试应用程序   2.2 启动Java Persistence项目   2.2.1 使用Hibernate Annotations   2.2.2 使用Hibernate EntityManager   2.2.3 引入EJB组件   2.2.4 切换...

    Hibernate注释大全收藏

    • 将类注解为 @IdClass,并将该实体中所有主键的属性都注解为 @Id @Entity @IdClass(FootballerPk.class) public class Footballer { //part of the id key @Id public String getFirstname() { return ...

    Hibernate 中文 html 帮助文档

    1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. 映射Person类 1.3.2. 单向Set-based的关联 1.3.3. 使关联工作 1.3.4. 值类型的集合 ...

    最全Hibernate 参考文档

    5.4.2. 使用 JDK 5.0 的注解(Annotation) 6. 集合类(Collections)映射 6.1. 持久化集合类(Persistent collections) 6.2. 集合映射( Collection mappings ) 6.2.1. 集合外键(Collection foreign keys) 6.2.2. 集合...

    Hibernate教程

    2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 - 关联映射 2.3.1. 映射Person类 2.3.2. 一个单向的Set-based关联 2.3.3. 使关联工作 2.3.4. 值类型的集合...

    Hibernate3的帮助文档

    2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 - 关联映射 2.3.1. 映射Person类 2.3.2. 一个单向的Set-based关联 2.3.3. 使关联工作 2.3.4. 值类型的集合...

    hibernate3.04中文文档.chm

    2.2.3. Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 - 关联映射 2.3.1. 映射Person类 2.3.2. 一个单向的Set-based关联 2.3.3. 使关联工作 2.3.4. 值...

    Hibernate3+中文参考文档

    5.4.2. 使用 JDK 5.0 的注解(Annotation) 6. 集合类(Collections)映射 6.1. 持久化集合类(Persistent collections) 6.2. 集合映射( Collection mappings ) 6.2.1. 集合外键(Collection foreign keys) 6.2.2. 集合...

    hibernate 框架详解

    Hibernate配置 2.2.4. 用Ant编译 2.2.5. 安装和帮助 2.2.6. 加载并存储对象 2.3. 第二部分 - 关联映射 2.3.1. 映射Person类 2.3.2. 一个单向的Set-based关联 2.3.3. 使关联工作 2.3.4. 值类型的集合 ...

    Hibernate参考文档

    1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. 映射Person类 1.3.2. 单向Set-based的关联 1.3.3. 使关联工作 1.3.4. 值类型的集合 ...

    Spring.3.x企业应用开发实战(完整版).part2

    4.10.2 使用注解配置信息启动Spring容器 4.10.3 自动装配Bean 4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean定义信息 4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 ...

    Spring3.x企业应用开发实战(完整版) part1

    4.10.2 使用注解配置信息启动Spring容器 4.10.3 自动装配Bean 4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean定义信息 4.11.2 使用基于Java类的配置信息启动Spring容器 4.12 ...

    springmybatis

    MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录. orm工具的基本思想 无论是用过的hibernate,mybatis,你都可以法相他们有一个...

    JAVA上百实例源码以及开源项目

    从内存中清除,从账户中取出amt,如果amt>账户余额抛出异常,一个实体Bean可以表示不同的数据实例,我们应该通过主键来判断删除哪个数据实例…… ejbCreate函数用于初始化一个EJB实例 5个目标文件,演示Address ...

    JAVA上百实例源码以及开源项目源代码

    保证Bean正常被激活和钝化,EJB对象是用完毕,从内存中清除,从账户中取出amt,如果amt>账户余额抛出异常,一个实体Bean可以表示不同的数据实例,我们应该通过主键来判断删除哪个数据实例…… ejbCreate函数用于初始...

Global site tag (gtag.js) - Google Analytics