one-to-many 的级联删除 把我折磨惨了.
首先 我一直想避免先把 对象查找出来  然后再删除.
 所以我就准备先删除子表(就是many一段),然后再删除父表(就是one一端的数据),但是这是不可以的....
关于网上什么的 cascade='all' 我都试过了,也米有效果.如上的不成功,所以我就直接使用 
getHibernateTemplate().execute(new HibernateCallback(){
public Object doInHibernate(Session session)
})
如上的方法直接 用session来删除 也是不可以的.
然后我又使用网上 广为流传的 hql 删除级联的 写法 也是不正确的.
举个例子
A one-to-many B
String  hql="DELETE FROM A a, B b WHERE b.a.id=a.id and a.id=?"
或是
String  hql="DELETE a  FROM A a, B b WHERE b.a.id=a.id and a.id=?"
都是不可以的..此处我注明下 我用的是 MySql ssh架构...
有人说是 事务的原因我把我的事务处理也贴出来
<tx:method name="get*" read-only="true" propagation="REQUIRED"/>
<tx:method name="*"  propagation="REQUIRED"/>+
请各位高手 根据自己的经验来 搞下..
我觉得主要解决的目标就是 不用先查出对象就可以根据hql进行删除.

解决方案 »

  1.   

    以下是我做的级联删除树的,希望对你有帮助package com.hhd.zxg.dao;import java.util.List;
    import java.util.Set;import org.springframework.stereotype.Component;import com.hhd.zxg.bean.Category;@Component(value = "categoryDao")
    public class CategoryDaoImpl extends DaoImpl implements CategoryDao { @Override
    public void delete(Category c) { Category category = (Category) hibernateTemplate.load(Category.class, c.getId());

    if (category.getParent() == null) {
    deleteParent(category);
    } else {

    List<?> list = hibernateTemplate
    .find("from Product p where p.category.id=" + category.getId()); hibernateTemplate.flush();
    hibernateTemplate.clear();
    hibernateTemplate.deleteAll(list);
    hibernateTemplate.delete(category);
    } }

    /**
     * 有孩子
     */
    public void deleteParent(Category c) { Set<Category> children = c.getChildren(); if (children.size() == 0) {
    hibernateTemplate.delete(c);
    } else {
    for (Category category : children) {
    List<?> list = hibernateTemplate
    .find("from Product p where p.category.id="
    + category.getId());
    hibernateTemplate.flush();
    hibernateTemplate.clear();
    hibernateTemplate.deleteAll(list);
    hibernateTemplate.delete(category);
    } c.setChildren(null);
    hibernateTemplate.delete(c);
    } }}
      

  2.   

    cascade='all' 是所有操作都级联,这样配指定不行,你若是子表与父表全级联(就是many方配all),你在执行删除子表的同时,会级联删除父表,若父表和其他子表还有映射,就会出错;你若想单独删除某子表,就不要配级联删除,直接删了就可以,要是想删除父表,就把父类该字段所有关联的子表查出,删除掉以后,再来删除父表就不会出错了。
      

  3.   

    就把父类该字段所有关联的子表查出. 我就是想解决这种效率问题,直接删除,不用再查询.
    利用hql
      

  4.   

    各位我想解决的问题是在我知道 one 一端的id后 删除主表和字表对应的所有数据,
    这里大家都是推荐的 先查出这些数据,然后删除.
    而我想避免这种效率浪费,直接删除,不要再查询了.
    这是主要目标,请大家看清问题......
      

  5.   

    你 就  在 one 这一端 设置 cascade = "delete" 应该就好了
      

  6.   

     
    例如 hql="delete from A a where a.id=?"
    这样是么....
    大哥您这么写过么,没写过没成功的最好别说出来,误导人啊.....
      

  7.   

    以前用的是:先根据单端查询出多端,删除多端,最后删除单端。不查询直接删除你这样试试:
    @ManyToOne(fetch = FetchType.LAZY)
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
      

  8.   

    好像可以配置一个反转吧。也就是把控制权交给单的一方去做,就不会了,不然还是hql吧,应该是可以的
      

  9.   

    在one的一段 我用了inverse='true' one的一端放弃了权利的维护.
    貌似是这个,但是规范好像是 都是one的一段放弃关系的维护.
      

  10.   


    这位老兄 根据你的思路 还是要查询, 
    而且就算按照你的 思路来的话,  可以在查询单端的时候join fetch 出多端,
    然后直接删除单端,附带多端也会删除.
    这个方法是可行的,比你的方法少了次数据库查询