hibernate 一对多

2017-10-30  本文已影响33人  siriusing

1.0 最基本的双向一对多

<?xml version="1.0" encoding="UTF-8"?>
<!-- Parent.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
    <class name="Parent" table="t_Parent"  >
    
        <id name="pid" column="pid">
            <generator class="native"></generator>
        </id>
        <property name="name"></property>

        <set name="children" >
            <key column="pid" ></key>
            <one-to-many class="Chird" />
        </set>
    </class>

</hibernate-mapping>



<?xml version="1.0" encoding="UTF-8"?>
<!-- Chird.hbm.xml -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cc.sirius.bean">
    <class name="Chird" table="t_Chird"  >
    
        <id name="cid" column="cid">
            <generator class="native"></generator>
        </id>
        <property name="name"></property>

        <many-to-one name="parent" class="Parent" column="pid" not-null="true"></many-to-one>
    </class>

</hibernate-mapping>

1.1 添加

    @Test
    public void addParent(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Parent p=new Parent("花老");
        
        Chird c1=new Chird("花花");
        Chird c2=new Chird("利利");
    
        c1.setParent(p);
        c2.setParent(p);    
        p.getChildren().add(c1);
        p.getChildren().add(c2);
        

        session.save(p);
        session.save(c1);
        session.save(c2);
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();    
    }

1.2 修改

    @Test
    public void updateChildByParent(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        
        Parent p = (Parent) session.get(Parent.class, 1);
        Iterator<Chird> it = p.getChildren().iterator();
        
        while(it.hasNext()){
            it.next().setName("老花的孩子");
        }
        
        session.save(p);
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
        
    }
    
Hibernate: 
    select
        parent0_.pid as pid1_0_,
        parent0_.name as name1_0_ 
    from
        t_Parent parent0_ 
    where
        parent0_.pid=?
Hibernate: 
    select
        children0_.pid as pid1_1_,
        children0_.cid as cid1_,
        children0_.cid as cid0_0_,
        children0_.name as name0_0_,
        children0_.pid as pid0_0_ 
    from
        t_Chird children0_ 
    where
        children0_.pid=?
Hibernate: 
    update
        t_Chird 
    set
        name=?,
        pid=? 
    where
        cid=?
Hibernate: 
    update
        t_Chird 
    set
        name=?,
        pid=? 
    where
        cid=?

1.3 删除

@Test
    public void deleteParent(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        
        Parent p = (Parent) session.get(Parent.class, 1);
        
        session.delete(p);
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
        
    }

执行后报错,这里原因是child那里我们设置了not null,去修改一下

org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
    at ...

<class name="Chird" table="t_Chird"  >
    
        <id name="cid" column="cid">
            <generator class="native"></generator>
        </id>
        <property name="name"></property>

        <many-to-one name="parent" class="Parent" column="pid"></many-to-one>
    </class>

再运行一把

Hibernate: 
    select
        parent0_.pid as pid1_0_,
        parent0_.name as name1_0_ 
    from
        t_Parent parent0_ 
    where
        parent0_.pid=?
Hibernate: 
    update
        t_Chird 
    set
        pid=null 
    where
        pid=?
Hibernate: 
    delete 
    from
        t_Parent 
    where
        pid=?

他会把chrid的parent设置为null

1.4考虑一下级联保存


@Test
    /*
     * 考虑一下级联保存
     */
    public void addParentOnly(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        Parent p=new Parent("花老");
        
        Chird c1=new Chird("花花");
        Chird c2=new Chird("利利");
    
        c1.setParent(p);
        c2.setParent(p);    
        p.getChildren().add(c1);
        p.getChildren().add(c2);
        

        session.save(p);
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
        
    }

出错,这里主要是因为没设置级联,我们设置一下级联

<!--parent-->

        <set name="children" cascade="all">
            <key column="pid" ></key>
            <one-to-many class="Chird" />
        </set>

结果

Hibernate: 
    insert 
    into
        t_Parent
        (name) 
    values
        (?)
Hibernate: 
    insert 
    into
        t_Chird
        (name, pid) 
    values
        (?, ?)
Hibernate: 
    insert 
    into
        t_Chird
        (name, pid) 
    values
        (?, ?)
Hibernate: 
    update
        t_Chird 
    set
        pid=? 
    where
        cid=?
Hibernate: 
    update
        t_Chird 
    set
        pid=? 
    where
        cid=?

2.0 parent 放弃关联 inverse=true

        <set name="children"  inverse="true">
            <key column="pid" ></key>
            <one-to-many class="Chird" />
        </set>

2.1 添加

调用上面的addParent没问题

image.png

2.2考虑修改

@Test
    public void updateChildByParent(){
        
        Session session = HibernateUtils.openSession();
        session.beginTransaction();
        // ------------------------------------------------------
        
        Parent p = (Parent) session.get(Parent.class, 1);
        Iterator<Chird> it = p.getChildren().iterator();
        
        while(it.hasNext()){
            it.next().setName("老花的孩子");
        }
        
        session.save(p);
        // ------------------------------------------------------
        session.getTransaction().commit();
        session.close();
        
    }

也没问题

2.3 删除

出错

Hibernate: 
    select
        parent0_.pid as pid1_0_,
        parent0_.name as name1_0_ 
    from
        t_Parent parent0_ 
    where
        parent0_.pid=?
Hibernate: 
    delete 
    from
        t_Parent 
    where
        pid=?


org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update
    at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:96)
    at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:66)
    at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:275)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:268)
    at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:189)
    at ...

这里的原因还是因为没有加上级联删除

        <set name="children" inverse="true" cascade="all">

加上后就没事了

ps:这里一般都要配上级联操作,方便保存

上一篇 下一篇

猜你喜欢

热点阅读