`

Hibernate中联合主键映射时有一个也是外键的一种解决方法

阅读更多
     昨天遇到一个联合主键的问题,困扰了我很久,最后发现《Hibernate in Action》里有讲到,因为在实际环境中老是报错,也不知配置的对不对,然后回家写了一个DEMO,发现可以保存。
表结构大致如下:
ITEM(ID,NAME)其中id是PK
CATEGORY(ID,NAME),其中ID是PK
CATEGORY_ITEM(ITEM_ID,CATEGORY_ID,THIRD_ID,ADDED_DATE),其中ITEM_ID,CATEGORY_ID分别是ITEM和CATEGORY的外键,而他们与THIRD_ID一起组成CATETORY_ITEM表的联合主键。
下面给出具体实现:
一、Item.java

/**
 * @author Terrence
 *
 */
public class Item implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private Set<CategorizedItem> categorizedItems = new HashSet<CategorizedItem>();
	/**
	 * 
	 */
	public Item() {
		super();
	}
	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}
	/**
	 * @param id the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @return the categorizedItems
	 */
	public Set<CategorizedItem> getCategorizedItems() {
		return categorizedItems;
	}
	/**
	 * @param categorizedItems the categorizedItems to set
	 */
	public void setCategorizedItems(Set<CategorizedItem> categorizedItems) {
		this.categorizedItems = categorizedItems;
	}
	
	
}

二、Category.java
/**
 * @author Terrence
 *
 */
public class Category implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private Set<CategorizedItem> categorizedItems = new HashSet<CategorizedItem>();
	
	public Category() {
		super();
	}
	/**
	 * @return the id
	 */
	public Integer getId() {
		return id;
	}
	/**
	 * @param id the id to set
	 */
	public void setId(Integer id) {
		this.id = id;
	}
	/**
	 * @return the name
	 */
	public String getName() {
		return name;
	}
	/**
	 * @param name the name to set
	 */
	public void setName(String name) {
		this.name = name;
	}
	/**
	 * @return the categorizedItems
	 */
	public Set<CategorizedItem> getCategorizedItems() {
		return categorizedItems;
	}
	/**
	 * @param categorizedItems the categorizedItems to set
	 */
	public void setCategorizedItems(Set<CategorizedItem> categorizedItems) {
		this.categorizedItems = categorizedItems;
	}
	
	
}

三、CategorizedItem.java

/**
 * @author Terrence
 *
 */
public class CategorizedItem implements Serializable {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static class Id implements Serializable {

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		private Integer thirdId;
		private Integer categoryId;
		private Integer itemId;
		/**
		 * 
		 */
		public Id() {
			super();
		}
		
		/**
		 * @return the thirdId
		 */
		public Integer getThirdId() {
			return thirdId;
		}

		/**
		 * @param thirdId the thirdId to set
		 */
		public void setThirdId(Integer thirdId) {
			this.thirdId = thirdId;
		}

		/**
		 * @return the categoryId
		 */
		public Integer getCategoryId() {
			return categoryId;
		}
		/**
		 * @param categoryId the categoryId to set
		 */
		public void setCategoryId(Integer categoryId) {
			this.categoryId = categoryId;
		}
		/**
		 * @return the itemId
		 */
		public Integer getItemId() {
			return itemId;
		}
		/**
		 * @param itemId the itemId to set
		 */
		public void setItemId(Integer itemId) {
			this.itemId = itemId;
		}
		/* (non-Javadoc)
		 * @see java.lang.Object#hashCode()
		 */
		@Override
		public int hashCode() {
			return this.categoryId.hashCode()+this.itemId.hashCode();
		}
		/* (non-Javadoc)
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		@Override
		public boolean equals(Object obj) {
			if(obj!=null&&obj instanceof Id){
				Id that = (Id)obj;
				return this.categoryId.equals(that.categoryId)&&this.itemId.equals(that.itemId);
			}else{
				return false;
			}
		}
		
	}
	
	private Id id = new Id();
	private Date dateAdded;
	private Item item;
	private Category category;
	/**
	 * 
	 */
	public CategorizedItem() {
		super();
	}
	/**
	 * @return the id
	 */
	public Id getId() {
		return id;
	}
	/**
	 * @param id the id to set
	 */
	public void setId(Id id) {
		this.id = id;
	}
	/**
	 * @return the dateAdded
	 */
	public Date getDateAdded() {
		return dateAdded;
	}
	/**
	 * @param dateAdded the dateAdded to set
	 */
	public void setDateAdded(Date dateAdded) {
		this.dateAdded = dateAdded;
	}
	/**
	 * @return the item
	 */
	public Item getItem() {
		return item;
	}
	/**
	 * @param item the item to set
	 */
	public void setItem(Item item) {
		this.item = item;
		this.id.itemId = item.getId();
		item.getCategorizedItems().add(this);
	}
	/**
	 * @return the category
	 */
	public Category getCategory() {
		return category;
	}
	/**
	 * @param category the category to set
	 */
	public void setCategory(Category category) {
		this.category = category;
		this.id.categoryId = category.getId();
		category.getCategorizedItems().add(this);
	}
	/**
	 * @return the thirdId
	 */
	public Integer getThirdId() {
		return this.id.getThirdId();
	}

	/**
	 * @param thirdId the thirdId to set
	 */
	public void setThirdId(Integer thirdId) {
		this.id.thirdId = thirdId;
	}
	
}

四、*.hbm.xml,这里节省时间空间写在了一起
<hibernate-mapping package="org.terrence.hrsystem.model">
	<class name="Item" table="ITEM">
      <id name="id" type="integer" column="ITEM_ID">
         <generator class="identity" />
      </id>
      <property name="name" type="string" not-null="true"
         update="false" column="ITEM_NAME" />
      <set name="categorizedItems" cascade="all, delete-orphan"
         inverse="true" lazy="false">
         <key column="ITEM_ID" not-null="true" />
         <one-to-many class="CategorizedItem" />
      </set>
   </class>

<class name="Category" table="CATEGORY">
      <id name="id" type="integer" column="CATEGORY_ID">
         <generator class="identity" />
      </id>
      <property name="name" type="string" column="CATEGORY_NAME" not-null="true"/>
      <set name="categorizedItems" cascade="all, delete-orphan"
         inverse="true" lazy="false">
         <key column="CATEGORY_ID" not-null="true" />
         <one-to-many class="CategorizedItem" />
      </set>
   </class>

<class name="Category" table="CATEGORY">
      <id name="id" type="integer" column="CATEGORY_ID">
         <generator class="identity" />
      </id>
      <class name="CategorizedItem" table="CATEGORIZED_ITEM" mutable="false">
	<composite-id name="id" class="CategorizedItem$Id">
	<key-property name="thirdId" column="THIRD_ID" type="integer"/>
	<key-property name="categoryId" column="CATEGORY_ID"
				type="integer" />
	<key-property name="itemId" column="ITEM_ID" type="integer" />
	</composite-id>
	<property name="dateAdded" column="ADDED_ON" type="timestamp"
			not-null="true" />

	<many-to-one name="item" class="Item" column="ITEM_ID"
			not-null="true" insert="false" update="false" />
	<many-to-one name="category" class="Category" column="CATEGORY_ID"
			not-null="true" insert="false" update="false" />
	</class>
</hibernate-mapping>


五、测试代码
/**   
* @Title: TestDao.java 
* @Package test 
* @Description: TODO(用一句话描述该文件做什么) 
* @author Terrence.zhung 
* @date 2011-3-29 上午02:45:05 
* @version V1.0   
*/ 

package test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.terrence.hrsystem.dao.CategorizedItemDao;
import org.terrence.hrsystem.dao.CategoryDao;
import org.terrence.hrsystem.dao.ItemDao;
import org.terrence.hrsystem.model.CategorizedItem;
import org.terrence.hrsystem.model.Category;
import org.terrence.hrsystem.model.Item;

/**
 * @author Terrence
 *
 */
public class TestDao {

	/**
	 * @param args
	 */
	private static ItemDao itemDao;
	private static CategoryDao categoryDao;
	private static CategorizedItemDao  categorizedItemDao;
	private static ApplicationContext ctx;
	
	public static void init(){
		if(ctx==null){
			ctx = new ClassPathXmlApplicationContext(new String[]{"classpath:applicationContext.xml","classpath:daoContext.xml"});
		}
		itemDao = (ItemDao)ctx.getBean("itemDao");
		categoryDao = (CategoryDao)ctx.getBean("categoryDao");
		categorizedItemDao = (CategorizedItemDao)ctx.getBean("categorizedItemDao");
	}
	public static void main(String[] args) throws Exception {
		init();
		saveItem();
		saveCategory();
		saveCategoryItem();
	}
	
	public static void saveItem() throws Exception{
		Item item = new Item();
		item.setName("item2");
		itemDao.save(item);
	}
	
	public static void saveCategory() throws Exception{
		Category category = new Category();
		category.setName("category2");
		categoryDao.save(category);
	}
	
	public static void saveCategoryItem() throws Exception{
		Item item = itemDao.get(1);
		Category category = categoryDao.get(1);
		CategorizedItem categorizedItem = new CategorizedItem();
		categorizedItem.setItem(item);
		categorizedItem.setCategory(category);
		categorizedItem.setDateAdded(new java.util.Date());
		categorizedItem.setThirdId(5);
		categorizedItemDao.save(categorizedItem);
	}

}



六、说明
    因为用了spring,在配置文件配好环境,表可以用hibernate直接生成,不用写SQL语句。
分享到:
评论
3 楼 abcd880129 2011-11-07  
是不是写错了,应该是Item的主键、Category的主键是CategorizedItem的外键,然后又和thirdId组成CategorizedItem的联合主键,看标题让我兴奋了一下,原来不是
2 楼 zhongrf 2011-11-07  
168_ccxx 写道
CategorizedItem 的配置文件貌似没看到啊..

不好意思,贴错了,现在补上了,谢谢哈
1 楼 168_ccxx 2011-10-30  
CategorizedItem 的配置文件貌似没看到啊..

相关推荐

    Hibernate一对一单向外键关联 (联合主键annotation)

    通过这种方式,你可以实现Hibernate中一对一单向外键关联及联合主键的配置。这使得两个实体间的关系更加明确,同时也方便了数据的管理和操作。在实际项目中,这样的设计可以提高数据的完整性和一致性。

    Hibernate教程08_关系映射之联合主键

    例如,在`s2sh_relation05_one2one_uni_fk_composite`的示例中,假设我们有一个`Student`实体和一个`Address`实体,它们之间存在一对一(One-to-One)的关系,并且`Address`使用联合主键。`Address`实体的主键可能...

    hibernate的多种映射关系

    Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库,消除了直接编写 SQL 的需要。在 Hibernate 中,映射关系是将数据库表与 Java 类之间的关联方式,使得对象模型可以与关系...

    SSH2+JSO与三表联合主外键

    在描述中提到的“三表联合主键”,意味着可能涉及三个表的相互关联,每个表都有自己的主键,并且这些主键组合在一起形成了一个联合主键。这通常发生在复杂的关系型数据库设计中,例如在实现多对多关系或者需要更严格...

    hibernate之关于关联映射的综合应用

    在Hibernate中,关联映射主要有以下几种类型:一对一(OneToOne)、一对多(OneToMany)、多对一(ManyToOne)和多对多(ManyToMany)。在给定的示例中,涉及到的是多对多(ManyToMany)和一对多(OneToMany)的关联...

    Hibernate 的关联映射

    在Hibernate中,使用`@ManyToMany`注解,并创建一个中间表(通常是联合主键)来存储关联。`@JoinTable`注解用于定义中间表的详细信息。 关联映射时的注意事项: - 使用外键:Hibernate支持实体间的外键关联,但也...

    hibernate关联关系映射

    在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者将数据库操作转换为面向对象的方式,从而简化了数据访问层的编程。"hibernate关联关系映射"是Hibernate的核心概念之一,它定义了如何...

    hibernate 一对一双向带关联表映射练习

    在IT领域,尤其是在Java开发中,Hibernate是一个非常重要的对象关系映射(ORM)框架,它极大地简化了数据库操作。本文将深入探讨“hibernate 一对一双向带关联表映射”的概念及其实践,结合提供的资源...

    hibernate继承映射.rar

    例如,在Hibernate-lab2中,如果我们有一个基类`Person`和两个子类`Student`和`Teacher`,那么它们都会映射到同一张`Person`表中,通过discriminator值来区分它们的类型。 三、联合继承( Joined Table Inheritance...

    用Hibernate映射继承关系

    除了继承关系,描述中还提到了Hibernate的关联映射,这是另一个核心概念: - **一对一(One-to-One)映射**:一个实体与另一个实体有唯一的关系,例如一个人只有一个身份证。可以使用`@OneToOne`注解实现,可以是...

    hibernate映射继承关系(每个类都对应一张表)

    总结起来,"每个类都对应一张表"的继承映射策略在Hibernate中是一种直接且易于理解的方法,适合那些每个类都有独特属性的情况。然而,它可能不适合所有场景,特别是当子类众多或者需要减少数据冗余时。在实际应用中...

    hibernate映射关系

    在Java持久化框架Hibernate中,映射关系是数据库表与对象模型之间的一种关联方式,它使得数据操作可以更加便捷地在对象层面上进行。本文将深入探讨Hibernate中的三种主要映射关系:一对一(One-to-One)、一对多...

    hibernate中文帮助文档

    10. **多对一、一对多、多对多关联映射**: Hibernate支持各种复杂的关联关系,如实体间的关联映射配置,如外键、联合主键等。 综上,这份压缩包提供的文档涵盖了Hibernate的基本使用到高级特性,结合SQL参考手册,...

    hibernate之一对一关联映射

    一对一关联映射在Hibernate中表示两个实体类之间存在一对一的关系,也就是说,每个实体类的对象只对应另一个实体类的一个对象。这种映射关系可以是单向或双向的,并且可以通过外键或者主键来实现。接下来我们将深入...

    Hibernate表关系总结(一对一,多对一,多对多)

    - 当两个表共享一个主键时,可以使用联合主键实现一对一关系。联合主键类需要实现`Serializable`接口,并重写`equals`和`hashCode`方法。 ```java @Entity @Table(name = "_husband") public class Husband { // ...

    hibernate annotations 中文参考手册

    - **外键关联**:在子表中添加一个外键来指向父表的主键。 - **联合映射**:适用于具有多个表继承层次的情况。 #### 配置和元数据生成 ##### 元数据生成 Hibernate 允许通过注解来自动生成数据库表结构。这种方式...

    hibernate组件之间的关联

    Hibernate 是一个开源的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库,而无需直接编写 SQL 查询。在 Hibernate 中,组件之间的关联是实现对象模型与数据库表之间映射的关键部分,它包括了一对...

    hibernate4.1中文api

    - **映射一对多关联**: 如何在一对多关联中使用外键或联合表。 - **自然id**: 使用非主键属性作为唯一标识。 - **任意**: 映射任意类型的数据。 - **属性**: 更多关于属性映射的细节。 - **hbm.xml特异性**: 在`.hbm...

Global site tag (gtag.js) - Google Analytics