<hibernate-mapping>
  <class table="DataChange" name="xxx.xxx.xxx.DataChange">
    <id name="id">
      <generator class="native"/>
    </id>
    <property name="changeName"/>
    <list table="DataChangeTable" name="dataChangeTables" lazy="false" cascade="delete">
      <key column="dataChangeId"/>
      <list-index column="tableIndex"/>
      <composite-element class="xxx.xxx.xxx.DataChangeTable">
        <property name="dataChangeTableCode"/>
        <property name="dataChangeTableName"/>
        <property name="databaseCode"/>
        <property name="databaseName"/>
      </composite-element>
    </list>
    <list table="NodeObject" name="nodeTargets" lazy="false" cascade="delete">
      <key column="dataChangeId"/>
      <list-index column="nodeIndex"/>
      <composite-element class="xxx.xxx.xxx.NodeObject">
        <property name="nodeObjectCode"/>
        <property name="nodeObjectName"/>
      </composite-element>
    </list>
    <property name="databaseCode"/>
    <property name="databaseName"/>
  </class>
</hibernate-mapping>
DataChange。hava 
中 有2个 list 分别是NodeObject,DataChangeTable  ,
DataChange 的id 关联到了 NodeObject,DataChangeTable  ,现在我要批量删除 DataChange  同时也要级联删除 NodeObject,DataChangeTable我现在的需求是   批量删除  DataChange    在hibernate  里面使用什么方法 可以达到这个要求  
我现在报的错误 是:
org.hibernate.exception.ConstraintViolationException: could not execute update query
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:84)
at org.hibernate.hql.ast.QueryTranslatorImpl.executeUpdate(QueryTranslatorImpl.java:396)
at org.hibernate.engine.query.HQLQueryPlan.performExecuteUpdate(HQLQueryPlan.java:259)
at org.hibernate.impl.SessionImpl.executeUpdate(SessionImpl.java:1141)
at org.hibernate.impl.QueryImpl.executeUpdate(QueryImpl.java:94)
at xxx.xxx.xxx.DatabaseDAOImpl.delDataChangeLists(DatabaseDAOImpl.java:289)
at xxx.xxx.xxx.impl.DatabaseManagerImpl.delDataChangeLists(DatabaseManagerImpl.java:157)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:318)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:203)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:162)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:107)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:209)
at $Proxy7.delDataChangeLists(Unknown Source)
at com.hua.mt.test.DatabaseManagerTest.testdelDataChangeLists(DatabaseManagerTest.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at junit.framework.TestCase.runTest(TestCase.java:164)
at junit.framework.TestCase.runBare(TestCase.java:130)
at org.springframework.test.ConditionalTestCase.runBare(ConditionalTestCase.java:69)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:120)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: java.sql.SQLException: Cannot delete or update a parent row: a foreign key constraint fails (`mt2/mt_datachangetable`, CONSTRAINT `FKBDE8193C4C174A74` FOREIGN KEY (`dataChangeId`) REFERENCES `mt_datachange` (`id`))
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2975)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1600)
at com.mysql.jdbc.ServerPreparedStatement.serverExecute(ServerPreparedStatement.java:1125)
at com.mysql.jdbc.ServerPreparedStatement.executeInternal(ServerPreparedStatement.java:677)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1357)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1274)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1259)
at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:75)
... 35 more请问 hibernate的  删除  语句怎么写才好 
 高手指教了 谢谢啊  急!!!!!!!!!!!!!!!!!!!

解决方案 »

  1.   

    我现在使用的 是
    String hql = "select dc from  DataChange dc  where dc.id in ( " + sbStr.toString().substring(0, sbStr.toString().length()-1) + " ) ";   //里面输 id 的参数
    List list = this.getHibernateTemplate().find(hql); this.getHibernateTemplate().deleteAll(list);这个可以删除  但是 这个就是少量的  现在要考虑到大量 数据 的 批量删除 Caused by: java.sql.SQLException: Cannot delete or update a parent row: a foreign key constraint fails (`mt2/mt_datachangetable`, CONSTRAINT `FKBDE8193C4C174A74` FOREIGN KEY (`dataChangeId`) REFERENCES `mt_datachange` (`id`)) 
    这个问题是 我使用了 
    this.getSession().createQuery(hql).executeUpdate();这个不能级联删除   有什么方法没有 请赐教了
      

  2.   

    留楼 关注。。Caused by: java.sql.SQLException: Cannot delete or update a parent row: a foreign key constraint fails (`mt2/mt_datachangetable`, CONSTRAINT `FKBDE8193C4C174A74` FOREIGN KEY (`dataChangeId`) REFERENCES `mt_datachange` (`id`)) 
      

  3.   

    建议从多的一方进行删除。下面代码希望能对你有所帮助StringBuffer buffer=new StringBuffer("delete HemsCAssignment a where a.matchResultRowId in (:matchResultRowId)");
    Session session=this.getSessionFactory().getCurrentSession();
    Query query=session.createQuery(buffer.toString());
    query.setParameterList("matchResultRowId", list);
    query.executeUpdate();还有你加了lazy=false本身就是对性能的一种挑战,最好不要配置lazy=false,在需要读取的时候在读取
      

  4.   

    级联删除
    1、要么代码多一行,先去把父类的表数据删除了,才能删除子表的。不然外键被调用着。那么那条数据不能删除的2、在数据库里面写个级联删除的触发器trigger
      

  5.   

    看了下你的错误,应该是spring和hibernate一起使用的,
    用spring的hibernate模版的回调方法来删除时可以的public void deleteQuestion(Question question) throws DaoException {
    if (question == null || question.getId() == null) {
    return;
    }
    final Integer id = question.getId();
    try {
    List surveyItems = getHibernateTemplate().find("select count(*) from SurveyItem a where a.question.id = ?", id);
    if (surveyItems != null && !surveyItems.isEmpty()) {
    if (((Integer) surveyItems.get(0)).intValue() > 0) {
    throw new DaoException("该问题已被调查问卷选用, 不能被删除!    ");
    }
    }
    getHibernateTemplate().execute(new HibernateCallback() {
    public Object doInHibernate(Session session) throws HibernateException, SQLException {
    int result = session.createQuery("delete from Answer where question_id=:id").setParameter("id", id).executeUpdate();
    if (logger.isDebugEnabled()) {
    logger.debug("从答案中删除了" + result + "条记录.");
    }
    return new Integer(result);
    }
    });
    getHibernateTemplate().delete(question);
    } catch (DataAccessException e) {
    logger.error("删除问题失败");
    e.printStackTrace();
    throw new DaoException(e);
    }
    }
      

  6.   

    spring的hibernate中的deleteall也是循环实体进行删除,效率会降低楼主设置cascade="delete",实际上并不是删除数据吧,而是把外键字段设置成null,数据库中如果设置了不允许为空的话,会报错并不是真正意义上的删除,所以
    批量删除,最好是直接用hql或者用sql,从叶子删起,一直到根。可以用hibernatetemplate的bulkupdate进行删除操作
      

  7.   

    今天下午 比较忙 没有时间看了
     谢谢大家帮忙解答  还没有时间验证  时间紧 稍后 验证回复 7楼:
    还有你加了lazy=false本身就是对性能的一种挑战,最好不要配置lazy=false,在需要读取的时候在读取 开始的时候 lazy 我是true得  后来 由于 一些原因 要在 web 启动的时候 就要查询 数据库 由于 使用了 spring + hibernate 而且 spring 注入问题 spring 注入servlte(初始化查询数据库 )bean 如果使用延迟lazy 就会 出问题web 启动时候 有 servlet 还有listener 都是自定义的 开始 就要查询数据库 做初始化 
    StringBuffer buffer=new StringBuffer("delete HemsCAssignment a where a.matchResultRowId in (:matchResultRowId)"); 
    我也试过 好像这样不能够级联删除。 报外键异常9楼:
    第一个方法我也了解, 我也想写jdbc 语句 来删除 但是由于使用hibernate  我想知道有没有什么号的方法 可以使用hibernate 做级联删除  就是  批量删除 1 父亲 的一端 然后 就会级联删除  关联多个 孩子在数据库里面写个级联删除的触发器trigger 
    这个我没有 使用过,  有没有例子 给个入门 非常需要 谢谢
    10 楼的:
      int result = session.createQuery("delete from Answer where question_id=:id").setParameter("id", id).executeUpdate();谢谢这个方法 我还没有测试不过我看了 这个删除语句 只是 删除 1个 object  不是我需要的效果
    如果 我页面 传递过来 的 是 一个String[] 里面包含了 大量要删除的 Answer 的id 现在 我要吧这些Answer  都删除了而且  还要级联删除 该 Answer  下面的所有的  SurveyItem  那么这样使用hibernate 会不会效率不行删除 一个对象  发2条 语句  所以也 也产生效率问题
    11楼:
    hibernatetemplate的bulkupdate 这个方法确实不知道 
    请大家多多指教!等过几天 就测试下大家的方法, 谢谢了
      

  8.   

    补充 :
    11楼的;可能我哪里设置错误了 楼主设置cascade="delete",实际上并不是删除数据吧 我是想删除掉  不是假删除 , 怎么设置才好??批量删除,最好是直接用hql 这个 hql 语句 要是什么格式的? 怎么批量??
    传入id 还是根据什么参数删除 谢谢指教!
      

  9.   

    cascade="delete"是清空关联字段,子表数据会变成孤立数据,可以配置cascade="all-delete-orphan",但是似乎需要一些修改,具体看下,希望你能看明白
    http://hi.baidu.com/landor2004/blog/item/d7bc760193d995031d95839a.htmlspring的bulkupdate其实就是hibernate的createquery,写hql就和写sql类似了
    delete from Xxx x where x.id in (...)