博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

【原创】hibernate中delete的一点见解

Posted on 2008-01-22 13:43    阅读(13999)  评论(0编辑  收藏  举报
需求:
    1.有两个类父类Parent和子类Child
    2.添加父类的时候同时添加子类
    3.删除父类时同时删除子类
    4.父类下子类的个数可能较多


Parent parent = new Parent();
 parent.setId(new Long(3));
 parent.setName("parent1");
 
1 . session.save(parent);
parent的id为重新生成的1
 
2 . session.persist(parent);
 报PersistentObjectException: detached entity passed to persist: com.css.wwl.hibrelationaldb.cascade.Parent
 
 
去掉setId后save和persist都能保存
            session.persist(parent);
            session.persist(parent);
            session.save(parent);
            session.save(parent);
    和
            session.save(parent);
            session.save(parent);
            session.persist(parent);
            session.persist(parent);
    结果一样 最终保存一个Parent 对象
persist的级联关联为 persist
save的级联关联为 save-update

 save中即使是新的对象为什么也没有persist级联通知?
 
 session.delete(parent);
如果parent的children已经初始化(包括之前同一session中执行parent= (Parent) session.load(Parent.class,parent.getId());),
若parent的cascade含有delete或delete-orphan
则:update Child  set parentId=null  where parentId=?
    delete from Child where id=?
    delete from Parent where id=?
否则只执行:
    update Child  set parentId=null  where parentId=?
    delete from Parent where id=?
 
如果parent的children没有初始化,同样只执行
    update Child  set parentId=null  where parentId=?
    delete from Parent where id=?
不会对Child进行删除
即使cascade为none 同样会执行 update Child  set parentId=null  where parentId=?
cascade为delete-orphan 并不会删除Child中parentId为null的对象
 
 
 
要想简单高效的级联删除可以手工写HSQL如下:
  String deleteChildrenSql="delete from "+ Child.class.getName()+" where parent.id = :parent";
 
 session.createQuery(deleteChildrenSql)
          .setParameter("parent",parent.getId()).executeUpdate();
       //  session.delete(parent);
        String deleteParentSql="delete from "+ Parent.class.getName()+ " as    parent where parent.id = :id";
         session.createQuery(deleteParentSql)
                 .setParameter("id",parent.getId())
                 .executeUpdate();
 
执行的sql为:
     delete from Child where parentId=?
     delete from Parent where id=?
where parent.id = :parent可以写成where parentId = :parent(参数传parent.getId())
或 where parent = :parent(参数传parent)
 
 

附:
Transitive persistence