`
bulebaby
  • 浏览: 42829 次
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Hibernate映射多对一关联

阅读更多
Hibernate映射多对一关联
关键字: hibernate映射多对一关联
自己总结:
一对一双向关联问题,比较复杂

Hibernate映射多对一关联,不能够双向关联,因为反过来变成多对一就产生了冗余。
数据库:SQL Server 2000
JDK版本:JDK 1.5
开发IDE:Ecclipse 3.2+MyEclipse 5.0
使用SQL Server2000数据库,新建数据库shirdrn,新建两张表teacher和student,分别如下所示:
教师表teacher:


学生表student:


从学生的角度看,与教师是多对一关联,即一个学生一定对应一个教师(而从教师角度看就是一对多,我们选定以学生为参照),所以在学生表的映射文件里面配置与教师的关联。其实,也就是我们的意图是想通过学生获取教师的信息,而不需要通过教师获取学生信息,这些是限定条件。所以必须能从Student的一方get到Teacher,因而就在学生里配置关联。
student表对应的映射文件和持久化类分别为:
映射文件Student.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">
<!--
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
    <class name="org.shirdrn.entity.Student" table="student">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="sno" type="java.lang.String">
            <column name="sno" length="10" not-null="true" />
        </property>
        <property name="sname" type="java.lang.String">
            <column name="sname" length="50" not-null="true" />
        </property>
        <property name="dept" type="java.lang.String">
            <column name="dept" length="50" />
        </property>
        <many-to-one name="teacher"
            column="id"
            class="org.shirdrn.entity.Teacher"
            insert="false"
            update="false"
            cascade="save-update">
        </many-to-one>
    </class>
</hibernate-mapping>
持久化类Student.java:
package org.shirdrn.entity;

/**
* Student generated by MyEclipse - Hibernate Tools
*/
public class Student implements java.io.Serializable { 
     private Integer id;
     private String sno;
     private String sname;
     private String dept;
     private Teacher teacher;
/** default constructor */
    public Student() {
    }
/** minimal constructor */
    public Student(String sno, String sname) {
        this.sno = sno;
        this.sname = sname;
    }
   
    /** full constructor */
    public Student(String sno, String sname, String dept) {
        this.sno = sno;
        this.sname = sname;
        this.dept = dept;
    }
  
    // Property accessors
    public Integer getId() {
        return this.id;
    }
   
    public void setId(Integer id) {
        this.id = id;
    }
    public String getSno() {
        return this.sno;
    }
   
    public void setSno(String sno) {
        this.sno = sno;
    }
    public String getSname() {
        return this.sname;
    }
   
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getDept() {
        return this.dept;
    }
   
    public void setDept(String dept) {
        this.dept = dept;
    }
public Teacher getTeacher() {
   return teacher;
}
public void setTeacher(Teacher teacher) {
   this.teacher = teacher;
}
  
}
teacher表对应的映射文件和持久化类分别为:
映射文件Teacher.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">
<!--
    Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
    <class name="org.shirdrn.entity.Teacher" table="teacher" schema="dbo" catalog="hibernate">
        <id name="id" type="java.lang.Integer">
            <column name="id" />
            <generator class="identity" />
        </id>
        <property name="tname" type="java.lang.String">
            <column name="tname" length="50" not-null="true" />
        </property>
    </class>
</hibernate-mapping>
持久化类Teacher.java:
package org.shirdrn.entity;

/**
* Teacher generated by MyEclipse - Hibernate Tools
*/
public class Teacher implements java.io.Serializable {

    // Fields  
     private Integer id;
     private String tname;

    // Constructors
    /** default constructor */
    public Teacher() {
    }
   
    /** full constructor */
    public Teacher(String tname) {
        this.tname = tname;
    }
  
    // Property accessors
    public Integer getId() {
        return this.id;
    }
   
    public void setId(Integer id) {
        this.id = id;
    }
    public String getTname() {
        return this.tname;
    }
   
    public void setTname(String tname) {
        this.tname = tname;
    }
}
建立测试类为MyTest.java如下:
package org.shirdrn.test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.shirdrn.HibernateSessionFactory;
import org.shirdrn.entity.Student;
import org.shirdrn.entity.Teacher;
public class MyTest {
public static void main(String[] args){
   Session session = HibernateSessionFactory.getSession();
   Transaction tx = null;
   try{
    tx = session.beginTransaction();
    Student stu = new Student();
    stu.setSno("2008002");
    stu.setSname("shirdrn");
    Teacher t = new Teacher();
    t.setTname("王老师");
    stu.setTeacher(t);
    session.save(stu);
    System.out.println("success");
    tx.commit();
   }
   catch(Exception e){
    tx.rollback();
    e.printStackTrace();
   }
   finally{
    HibernateSessionFactory.closeSession();
   }
}
}
在many-to-one里面配置了 cascade="save-update",级联存储更新。在向student表插入记录的同时,也在对应的teacher表里面插入一条记录,因为一个学生一定对应一个教师,而且配置了关联,而且又是级联保存,在控制台上可以看到:
Hibernate: insert into hibernate.dbo.teacher (tname) values (?) select scope_identity()
Hibernate: insert into student (sno, sname, dept) values (?, ?, ?) select scope_identity()
可以看到,是先向teacher表插入记录,当Hibernate映射文件加载的时候,检测到cascade="save-update"配置,在程序执行到stu.setTeacher(t);的时候,就已经确定要对teacher表执行insert操作。
如果 不设置 cascade="save-update",则只执行了一条插入语句,只向学生表插入了一条记录:
Hibernate: insert into student (sno, sname, dept) values (?, ?, ?) select scope_identity()
但是如果insert="false" update="false"没有指定,则会创建SessionFactory失败,出现下面的异常:
log4j:WARN No appenders could be found for logger (org.hibernate.cfg.Environment).
log4j:WARN Please initialize the log4j system properly.
%%%% Error Creating SessionFactory %%%%
org.hibernate.MappingException: Repeated column in mapping for entity: org.shirdrn.entity.Student column: id (should be mapped with insert="false" update="false")
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:504)
at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:526)
at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:544)
at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:335)
at org.hibernate.mapping.RootClass.validate(RootClass.java:188)
at org.hibernate.cfg.Configuration.validate(Configuration.java:839)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1000)
at org.shirdrn.HibernateSessionFactory.rebuildSessionFactory(HibernateSessionFactory.java:60)
at org.shirdrn.HibernateSessionFactory.getSession(HibernateSessionFactory.java:43)
at org.shirdrn.test.MyTest.main(MyTest.java:11)
Exception in thread "main" java.lang.NullPointerException
at org.shirdrn.test.MyTest.main(MyTest.java:26)
我认为异常的原因是重复配置导致的。因为insert和update的默认值都是true,表明Student随时可执行插入更新操作。而我们使用cascade="save-update"又配置了一次,虽然是在关联中配置的,但是Student也是关联的一方,因此异常提示Repeated column。
然而,并不是说,如果在Student.hbm.xml的many-to-one中配置insert="false" update="false"而且也不配置cascade="save-update",执行测试程序就不会执行插入操作了,象下面这样:
<many-to-one name="teacher"
            column="id"
            class="org.shirdrn.entity.Teacher"
            insert="false"
            update="false"
            >
        </many-to-one>
仍然可以向student表插入记录,因为那个配置insert="false" update="false"是对于关联来说的,但看Student本身,它的insert还是true,所以执行插入操作。
分享到:
评论
1 楼 amnotsuperior 2010-12-22  
    @ManyToOne
public Group getGroup() {
return group;
}
Annotation

相关推荐

    hibernate多对多关联映射

    在Java的持久化框架Hibernate中,多对多关联映射是一种常见的关系数据库模型映射方式,用于处理两个实体之间存在多个实例互相关联的情况。本文将深入探讨Hibernate如何实现多对多关联映射,并通过实际例子解析相关...

    Hibernate映射一对多关联关系

    ### Hibernate映射一对多关联关系 #### 知识点概览 - **概念解析**:一对多(One-to-Many)关联关系的概念及其在Hibernate中的实现方式。 - **域模型设计**:创建具有一个实体与多个实体关联的域模型。 - **关系...

    Hibernate双向一对一关联映射(注解版)

    本主题聚焦于“Hibernate双向一对一关联映射”的注解实现,这是一种高级的数据库设计模式,用于处理两个实体之间一对一的关系。 在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有...

    hibernate关联映射详解

    包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。

    Hibernate一对一主键关联映射(双向关联)

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是一种常见的关系数据库模型映射方式。这种关联通常发生在两个实体之间,且每个实体都只有一个对应的实例。本篇文章将详细探讨双向一对一主键关联映射...

    Hibernate一对一主键关联映射(单向关联)

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是常见的关系映射方式之一,尤其在处理两个实体之间存在唯一对应关系时非常有用。本篇将重点讲解如何实现一对一主键关联映射的单向关联,并通过一个...

    hibernate多对多关联映射(单项关联)

    在Java的持久化框架Hibernate中,多对多关联映射是一种常见的关系模型,它用于处理两个实体类之间存在多个对应关系的情况。这篇博客"hibernate多对多关联映射(单项关联)"深入探讨了如何在Hibernate中实现这种映射...

    hibernate 单向多对多关联映射练习

    本练习主要关注的是Hibernate中的单向多对多关联映射,这是一种常见的关系数据库设计模式,用于表示两个实体间复杂的关系。 在多对多关联中,两个实体类可以相互拥有多个实例,但只在一个方向上建立关联。例如,...

    hibernate一对一主键关联映射(单项关联)

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是一种常见的关系数据库模型。本篇将深入探讨在Hibernate中实现一对一主键关联映射的单项关联方式。这种关联意味着两个实体类共享相同的主键,即一个...

    hibernate双向多对多关联映射(注解版)

    在这个“hibernate双向多对多关联映射(注解版)”的主题中,我们将深入探讨如何使用Hibernate的注解配置来处理数据库中的双向多对多关联关系。 首先,多对多关联在数据库设计中是指两个实体之间存在多个对应关系,...

    hibernate一对一主键关联映射(双项关联)

    在Java的持久化框架Hibernate中,一对一(One-to-One)关联映射是一种常见的关系映射方式,用于表示两个实体之间一对一的对应关系。本篇主要探讨的是基于主键(Primary Key)的双向关联映射,这在实际项目中非常常见...

    hibernate双向一对多关联映射(注解版)

    在Java的持久化框架Hibernate中,双向一对多关联映射是一种常见的关系映射方式,它模拟了数据库中的外键关联,使得一个实体可以拥有多个另一个实体的实例。在这个注解版的实现中,我们将深入探讨如何使用Hibernate的...

    hibernate一对多关联映射(单向关联)

    在Java的持久化框架Hibernate中,一对多关联映射是一种常见的关系映射方式,它用于表示一个实体(如用户)可以拥有多个关联实体(如订单)。在这个场景中,"一"通常代表父实体,"多"代表子实体。这篇博客文章...

    hibernate 多对一映射关联配置

    本文将深入探讨Hibernate中的多对一映射关联配置,并结合具体的文档心得进行讲解。 首先,我们要了解多对一映射的基本概念。在数据库设计中,如果一个表(实体A)的某一列是另一个表(实体B)的主键,那么就存在...

    hibernate3.2(六)多对一关联映射

    在本篇关于“Hibernate3.2(六)多对一关联映射”的主题中,我们将深入探讨在Java Persistence API(JPA)框架下,如何利用Hibernate实现多对一的关联映射。Hibernate作为JPA的一个实现,是Java开发中常用的ORM...

    Hibernate一对多单向关联映射

    本篇主要探讨的是如何在Hibernate中实现一对多的单向关联映射。 一、概念理解 一对多关联意味着一个实体(如部门)可以有多个关联实体(如员工),而反过来,每个员工只属于一个部门。单向关联则表示只有部门知道其...

    hibernate关联映射实例

    本文将深入探讨“hibernate关联映射实例”中的关键知识点,包括一对多、多对多和继承映射,这些都是Hibernate中至关重要的概念。 1. **一对多关联映射**: 在现实世界中,一个实体可能会与多个其他实体相关联,...

    hibernate 双向多对多关联映射练习

    在Java的持久化框架Hibernate中,双向多对多关联映射是一种常见的数据关系模型,它允许两个实体类之间存在多个实例互相引用的情况。本练习旨在帮助开发者深入理解并熟练运用这种映射方式。通过以下详细讲解,我们将...

    Hibernate一对一唯一外键关联映射(双向关联)

    本篇将详细讲解如何使用Hibernate实现一对一唯一外键(Unique Foreign Key)关联映射,并以双向关联为例进行深入探讨。 一、Hibernate一对一关联类型 一对一关联在现实世界中很常见,例如一个人只有一个身份证,一...

    Hibernate一对一关联映射(注解)

    本话题主要探讨的是Hibernate中的一对一关联映射,这是一种将数据库中的单个表映射到Java对象模型中单个类的关系映射技术。通过注解方式实现一对一关联映射,可以避免传统的XML配置文件,使得代码更加简洁、易读。 ...

Global site tag (gtag.js) - Google Analytics