Hibernate复合主键的处理(一)

复合主键,由多个字段组成主键,例如,使用firstname和lastname组成主键。

可以通过两种方式确定主键,一种是基于实体类的复合主键,另一种是通过定义主键类来实现。
不管通过哪种方式,复合主键都需要实现equals方法和hashcode方法,以作为不同数据之间是别的标志。

一.基于实体类属性的复合主键
主键由实体类中的属性组成。

1.
配置文件TUser.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    
<class name="cn.blogjava.start.TUser" table="t_user" catalog="sample">
        
<composite-id>
            
<key-property name="lastname" column="lastname" type="string" />
            
<key-property name="firstname" column="firstname" type="string" />
        
</composite-id>

        
<property name="age" type="integer" column="age"/>
    
</class>
</hibernate-mapping>

2.
TUser.java
package cn.blogjava.start;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

/**
 * TUser generated by hbm2java
 
*/

public class TUser implements java.io.Serializable {

    
// Fields    

    
private Integer age;

    
private String firstname;

    
private String lastname;

    
public Integer getAge() {
        
return age;
    }

    
public void setAge(Integer age) {
        
this.age = age;
    }

    
public String getFirstname() {
        
return firstname;
    }

    
public void setFirstname(String firstname) {
        
this.firstname = firstname;
    }

    
public String getLastname() {
        
return lastname;
    }

    
public void setLastname(String lastname) {
        
this.lastname = lastname;
    }
    
    
public boolean equals(Object obj) {
        
if(!(obj instanceof
 TUser)) {
            
return false
;
        }
        
        TUser user 
=
 (TUser)obj;
        
return new
 EqualsBuilder()          // EqualsBuilder 和HashCodeBuilder均为apache common lang包中的工具类
            .appendSuper(
super
.equals(obj))
            .append(
this
.lastname, user.lastname)
            .append(
this
.firstname, user.firstname)
            .isEquals();        
    }
    
    
public int
 hasCode() {
        
return new HashCodeBuilder(-528253723-475504089
)
            .appendSuper(
super
.hashCode())
            .append(
this.lastname).append(this
.firstname)
            .toHashCode();
            
    }


}

3.
测试类HibernateTest.java
package cn.blogjava.start;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;


public class HibernateTest extends TestCase {
    
    Session session 
= null;
    
/**
     * JUnit中的setUp方法在TestCase初始化的时候会自动调用
     * 一般用于初始化公用资源
     
*/
    
protected void setUp() {
        
try {
            
/**
             * 可以采用hibernate.properties或者hibernate.cfg.xml
             * 配置文件的初始化代码
             * 
             * 采用hibernate.properties
             * Configuration config = new Configuration();
             * config.addClass(TUser.class);
             
*/
            
            
//采用hibernate.cfg.xml配置文件,与上面的方法对比,两个差异
            
//1.Configuration的初始化方式
            
//2.xml
            Configuration config = new Configuration().configure();
            SessionFactory sessionFactory 
= config.buildSessionFactory();
            session 
= sessionFactory.openSession();
            
        } 
catch (HibernateException e) {
            
// TODO: handle exception
            e.printStackTrace();
        }        
    }

    
/**
     * JUnit中的tearDown方法在TestCase执行完毕的时候会自动调用
     * 一般用于释放资源
     
*/    
    
protected void tearDown() {
        
try {
            session.close();        
        } 
catch (HibernateException e) {
            
// TODO: handle exception
            e.printStackTrace();
        }        
    }    
    
    
/**
     * 对象持久化测试(Insert方法)
     
*/        
    
public void testInsert() {
        Transaction tran 
= null;
        
try {
            tran 
= session.beginTransaction();
            TUser user 
= new TUser();
            user.setFirstname(
"bai");
            user.setLastname(
"yunfeng");
            user.setAge(
26);
            session.save(user);
            session.flush();
            tran.commit();
        } 
catch (HibernateException e) {
            
// TODO: handle exception
            e.printStackTrace();
            Assert.fail(e.getMessage());
            
if(tran != null) {
                
try {
                    tran.rollback();
                } 
catch (Exception e1) {
                    
// TODO: handle exception
                    e1.printStackTrace();
                }
            }
        }
    }
    
    
/**
     * 对象读取测试(Select方法)
     
*/            
    
public void testSelect(){
        TUser user 
= new TUser();
        user.setFirstname(
"bai");
        user.setLastname(
"yunfeng");
        
        user 
= (TUser)session.load(TUser.class, user);
        Assert.assertEquals(user.getAge().intValue(), 
26
);
    }
}

posted on 2006-06-29 21:58 baim 阅读(1496) 评论(1)  编辑  收藏 所属分类: 开源软件框架

评论

# re: Hibernate复合主键的处理(一) 2006-10-22 21:51 hibernate初学者

你好!
我的代码如下:
User.java
...

User.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="onlyfun.caterpillar.user" table="user" catalog="sample">

<composite-id>
<key-property name="name"
column="name"
type="java.lang.String"/>
<key-property name="phone"
column="phone"
type="java.lang.String"/>
</composite-id>
<property name="age" column="age" type="java.lang.Integer"/>
</class>

</hibernate-mapping>

HibernateTest.java
...

build.xml:
<project name="JNameIt" default="all">
<target name="setProperties" description="setup the common properties">
<property name="src.dir" value="src"/>
<property name="images.dir" value="images"/>
<property name="classes.dir" value="classes"/>
<property name="lib.dir" value="lib"/>
</target>

<path id="1">
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</path>

<path id="class.path">
<!-- Include our own classes, of course -->
<pathelement location="${classes.dir}" />
<!-- Include jars in the project library directory -->
<fileset dir="lib">
<include name="*.jar"/>
</fileset>
<pathelement path ="${classpath}"/>

</path>

<taskdef name="schemaexport"
classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
classpathref="class.path"/>

<schemaexport
properties="classes/hibernate.properties"
quiet="no"
text="no"
drop="no"
delimiter=";"
output="/schema-export.sql">
<fileset dir="images">
<include name="*.hbm.xml"/>
</fileset>
</schemaexport>


<target name="clean" depends="setProperties" description="clean up the previous built files or dirs">
<delete dir="${classes.dir}"/>
<delete file="${jar.file}"/>
</target>

<target name="prepareDir" depends="setProperties" description="prepare necessary dirs">
<mkdir dir="${classes.dir}"/>
<mkdir dir="${lib.dir}"/>
<!--
<copy todir="${classes.dir}/images">
<fileset dir="${images.dir}"/>
</copy>
-->
</target>

<target name="compile" depends="prepareDir" description="compile the source files">
<javac srcdir="./src" destdir="${classes.dir}"
classpathref="1"/>
<copy todir="${classes.dir}/onlyfun/caterpillar">
<fileset dir="${images.dir}"/>
</copy>
</target>

<target name="run" depends="compile">

<java fork="true" classname="onlyfun.caterpillar.HibernateTest" classpathref="1">
<classpath path="${classes.dir}"/>
</java>
</target>

<target name="all" depends="clean" description="perform all targets"/>
</project>

User.java,hibernate.java放在WEB-INF/SRC 下,User.hbm.xml放在WEB-INF/images下,build.xml放在WEB-INF,
程序结构和你基本一样,为什么用ant run 时出现:
D:\Apache Software Foundation\Tomcat 5.5\webapps\HibernateTest\WEB-INF\build.xml
:35: Schema text failed: component class not found: onlyfun.caterpillar.User的错误!好长时间都没解决,网上也找不到类似的错误!
谢谢你帮忙看一下!  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 
<2006年6月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

导航

常用链接

随笔分类(27)

随笔档案(28)

搜索

最新评论