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
没问题
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:这里一般都要配上级联操作,方便保存