hibernate级联映射

有级联时,可以直接删除one方,但不能直接删除many方

没有级联时,可以直接删除many方,但不能直接删除one方。。。


一对多,有级联关系时:


one-to-many的设置中:


one方的配置文件,set或list集合里配置cascade=“all”或者“all-delete-orphan”,相当于加了级联关系。
删除one方时,many方的相关数据也会被删掉。
但是要注意:
删除one方时,不能直接写“delete from One where id=?”
        会报错误,类似于该记录还有关联的子记录,不能直接删除,需要删子记录,才行。那为啥级联不起作用了呢。
经过一番思考,原来必须用session.delete(object);这个语句才行,所以必须先查后删,这样hibernate才能根据主键记录找到要删的对象,并把many方先删除,再删one方。。
保存操作时,如果one many都是新建的,则必须这样进行关联:one.setMany(manyList),然后保存one方,这是最正确的方式。如果写many.setOne(one)并且session.save(many)则保存,说one方数据不是transient数据。如果many.setOne(One)并且session.save(one),则只保存one方数据。
如果one方数据是从数据库里查出来的,many为新建的,则可以many.setOne(one),再session.save(many)
(感觉是set的主动方是谁,一般要save这个主动方,否则关联关系进不来)
        @Test/*有级联时,两个都是new的对象,用many方set one方保存one方,结果是只保存了one方*/
        public void test111(){
                Session session = HibernateUtil.getSession();
                Dept dept = new Dept();
                Emp emp1 = new Emp("张三");
                emp1.setDept(dept);
                session.save(dept);
                session.beginTransaction().commit();
                session.close();
        }
Hibernate: insert into t_dept values ( )


        @Test public void test10(){//最正确的写法,one.setMany()
                Session session = HibernateUtil.getSession();
                Dept dept = new Dept();
                Emp emp1 = new Emp("张三");
                Set<Emp> list =  new HashSet<Emp>();
                list.add(emp1);
                dept.setEmps(list);
                session.save(dept);
                session.beginTransaction().commit();
                session.close();
        }
Hibernate: insert into t_dept values ( )
Hibernate: insert into t_emp (ename) values (?)


        @Test public void test12(){//one方为数据库里已有的数据,many方为new的,可以many.setOne()再save(many)
                Session session = HibernateUtil.getSession();
                Dept dept = new Dept();
                session.save(dept);
                session.flush();
                
                Emp emp1 = new Emp("张三");
                emp1.setDept(dept);
                session.save(emp1);---------------改为save(dept)或update(dept)都不行!!!只会单独保存dept!!set主动方是谁,就要保存它
                session.beginTransaction().commit();
                session.close();
        }
Hibernate: insert into t_dept values ( )
Hibernate: insert into t_emp (ename, did) values (?, ?)




删除many方时,直接写session.delete();居然报错了。
ObjectDeleteException:deleted object would be re-saved by casade(remove deleted object from associations)
因为级联关系,无法删除many方,
解决办法是解除级联,如何解除呢?
可以感觉manY方取得one方对象,再取many集合列表将该many对象移除,在该many方设置one方为null.
thismany.getoneside().getManys().remove(thismany);
thisMany.setOne(null);
manyDao.delete(thisMany);


--------------------------------------------------------------------------------------------------------------------------------------------

映射文件中,<many-to-one>或<one-to-one>时,都会产生外键。


比如A表和B表,A和B是一对多的关系。
数据库底层建表时,A和B是两个独立的表,不存在外键,但映射文件有<many-to-one>什么的,产生外键,那么当one方找不到的时候,就会报异常,所以在one方要加not-found="ignore"来忽略。
如果,数据库建表时,A和B也明确指定外键了,映射文件是<many-to-one>,就不用加not-found="ignore",one方不存在时直接报null。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值