デバイス分類削除コード読みだし
に質問
先日、小何はデバイス管理2モジュールでデバイス分類(同時にデバイス分類承認チームを削除)を削除したとき、システムが異常を投げ出した.承認チームが削除に成功し、デバイス分類の削除に成功しなかったことを示します.この問題を明確に説明するために、デバイス分類と承認チームの関係(hibernateマッピング関係)について説明します.
Hibernateマッピング関係
デバイス分類のmanagerコードブロックを削除します.
com.kedacom.ksoa3.apparatus2.domain.manager.ApparatusTypeManagerImpl.removeApparatusType
削除時に異常が発生した情報
異常発生時のSQL情報
分析とデバッグプロセス全体がSpringトランザクション制御の下にありますか? で調べたところ、Springトランザクション制御の下で行われています.
Hibernate SQL印刷を開く では、teamの削除とtypeの削除の順序が私たちが指定したのとは正反対の「例外発生時のSQL情報」が表示されています.どうしてこんなことになったの?私たちは最後に答えを出した.
Hibernateのカスケード削除を試み、typeを削除すると同時にteamをカスケード削除する は効果がありません.私たちはsql文を使用してtypeを削除しているので、このsql文はカスケード削除を開始しません.オブジェクトに対する操作のみが、そのプロパティに対するカスケード操作を開始できます.
hibernateはSQLの実行順序を変更しました.inverseの問題ですか? (後にinverseの問題ではなくhiberanateがキャッシュをクリーンアップするメカニズムが原因であることが判明した)この推測によれば、teamを削除するときにsessionを手動でクリーンアップすれば、hibernateはSQLの実行順序を変更しないと考えられている.そこで、A p a r a t u s TypeTeamDaoHibernateImplがteamを削除する動作を変更しました(コードを変更した後、問題解決):
com.kedacom.ksoa3.apparatus2.domain.dao.ApparatusTypeTeamDaoHibernateImpl.remove
最後に、Hibernateが私たちのsqlの実行順序を変更する理由を説明します.Hibernate Sessionがクリーンアップするとき、sqlの実行順序を実行します.
Hibernate Sessionはキャッシュをクリーンアップするとき、Sql文をどのような順序で実行しますか?http://www.wangchao.net.cn/bbsdetail_854253.htmlアプリケーションがSession.Save()メソッドを呼び出す順番に、エンティティを挿入するすべてのinsert文を実行します. エンティティを更新するすべてのupdate文を実行します. コレクションを削除するdelete文をすべて実行します. は、集合要素を更新、削除、挿入するすべてのsql文を実行する. は、セットを挿入するすべてのinsert文を実行する. アプリケーションがSesson.delete()メソッドを呼び出す順に、エンティティを削除するdelete文をすべて実行します.
上記の説明によると、私たちのコードではまず2つのgetから2つのselect文が生成されます.そして私たちのコードdeleteはteamオブジェクトです.delete typeのsql文をもう1つ実行します(私たちのr e m o v eApparatusChildrenTypeは実際にはsql文でtypeオブジェクトを削除します).
typeはteamの属性でもあるため、4番目の「集合要素を更新、削除、挿入するすべてのsql文を実行する」に従ってdelete typeのsql文を先に実行し、6番目の「アプリケーション呼び出しSesson.delete()メソッドの前後順に、エンティティを削除するすべてのdelete文を実行する」に従ってdelete teamオブジェクトの文を実行します.
先日、小何はデバイス管理2モジュールでデバイス分類(同時にデバイス分類承認チームを削除)を削除したとき、システムが異常を投げ出した.承認チームが削除に成功し、デバイス分類の削除に成功しなかったことを示します.
Hibernateマッピング関係
--many-to-one-->
--one-to-one-->
com.kedacom.ksoa3.apparatus2.domain.manager.ApparatusTypeManagerImpl.removeApparatusType
ApparatusTypePO type = typeDao.getById(typeId);
ApparatusTypeTeamPO team = type.getApparatusTypeTeam();
if (team != null) {
teamDao.remove(team);
}
if (!this.removeApparatusChildrenType(typeId)) {
return Message.getMessage(false, " , !");
}
2009-09-11 11:11:58 [ERROR] Duplicate key or integrity constraint violation message from server: "Cannot delete or update a parent row: a foreign key constraint fails (`ksoa3/apparatus2_type_team`, CONSTRAINT `FK78347D72721385C6` FOREIGN KEY (`type_id`) REFERENCES `apparatus2_type` (`id`))"
<org.hibernate.util.JDBCExceptionReporter>
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 com.kedacom.common.base.domain.dao.BaseDaoHibernateImpl$1.doInHibernate(BaseDaoHibernateImpl.java:271)
at org.springframework.orm.hibernate3.HibernateTemplate.doExecute(HibernateTemplate.java:419)
at org.springframework.orm.hibernate3.HibernateTemplate.execute(HibernateTemplate.java:339)
at com.kedacom.common.base.domain.dao.BaseDaoHibernateImpl.executeHql(BaseDaoHibernateImpl.java:264)
at com.kedacom.components.tree.manager.impl.TreeNodeManagerImpl.removeTreeNodeAndDescendants(TreeNodeManagerImpl.java:623)
at com.kedacom.components.tree.manager.impl.TreeNodeManagerImpl.removeLeaf(TreeNodeManagerImpl.java:596)
at com.kedacom.ksoa3.apparatus2.domain.manager.ApparatusTypeManagerImpl.removeApparatusChildrenType(ApparatusTypeManagerImpl.java:103)
at com.kedacom.ksoa3.apparatus2.domain.manager.ApparatusTypeManagerImpl.removeApparatusType(ApparatusTypeManagerImpl.java:216)
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:585)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:307)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:182)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:149)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy73.removeApparatusType(Unknown Source)
at com.kedacom.ksoa3.apparatus2.web.controller.ApparatusTypeController.delete(ApparatusTypeController.java:118)
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:585)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.doInvokeMethod(HandlerMethodInvoker.java:421)
at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:136)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:326)
at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:313)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:875)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:807)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:571)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:511)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.automatedlogic.domino.sso.DominoLoginFilter.doFilter(DominoLoginFilter.java:87)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:96)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:286)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:845)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread
.run(Thread
.java:595)
Caused by: java.sql.SQLException: Duplicate key or integrity constraint violation message from server: "Cannot delete or update a parent row: a foreign key constraint fails (`ksoa3/apparatus2_type_team`, CONSTRAINT `FK78347D72721385C6` FOREIGN KEY (`type_id`) REFERENCES `apparatus2_type` (`id`))"
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2001)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1168)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:1279)
at com.mysql.jdbc.Connection.execSQL(Connection.java:2281)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1825)
at com.mysql.jdbc.PreparedStatement.executeUpdate(PreparedStatement.java:1667)
at org.apache.tomcat.dbcp.dbcp.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:102)
at org.hibernate.hql.ast.exec.BasicExecutor.execute(BasicExecutor.java:75)
... 57 more
// tree_node、tree
select type.*, team.* from apparatus2_type type left outer
join apparatus2_type_team team on team.type_id=type.id where type.id=?
select team.* from apparatus2_type_team team where team.type_id=?
delete from apparatus2_type where tree_id='3' and left_node>=2 and right_node<=3
2009-09-11 11:11:58 [WARN] SQL Error: 1451, SQLState: 23000 <org.hibernate.util.JDBCExceptionReporter>
2009-09-11 11:11:58 [ERROR] Duplicate key or integrity constraint violation message from server: "Cannot delete or update a parent row: a foreign key constraint fails (`ksoa3/apparatus2_type_team`, CONSTRAINT `FK78347D72721385C6` FOREIGN KEY (`type_id`) REFERENCES `apparatus2_type` (`id`))"
<org.hibernate.util.JDBCExceptionReporter>
org.hibernate.exception.ConstraintViolationException: could not execute update query
...
delete from apparatus2_type_team where id=?
分析とデバッグ
com.kedacom.ksoa3.apparatus2.domain.dao.ApparatusTypeTeamDaoHibernateImpl.remove
public boolean remove(ApparatusTypeTeamPO team){
super.remove(team);
super.getHibernateTemplate().flush();
return true;
}
最後に、Hibernateが私たちのsqlの実行順序を変更する理由を説明します.Hibernate Sessionがクリーンアップするとき、sqlの実行順序を実行します.
Hibernate Sessionはキャッシュをクリーンアップするとき、Sql文をどのような順序で実行しますか?http://www.wangchao.net.cn/bbsdetail_854253.html
上記の説明によると、私たちのコードではまず2つのgetから2つのselect文が生成されます.そして私たちのコードdeleteはteamオブジェクトです.delete typeのsql文をもう1つ実行します(私たちのr e m o v eApparatusChildrenTypeは実際にはsql文でtypeオブジェクトを削除します).
typeはteamの属性でもあるため、4番目の「集合要素を更新、削除、挿入するすべてのsql文を実行する」に従ってdelete typeのsql文を先に実行し、6番目の「アプリケーション呼び出しSesson.delete()メソッドの前後順に、エンティティを削除するすべてのdelete文を実行する」に従ってdelete teamオブジェクトの文を実行します.