hibernate在DB2数据库上使用报DB2 SQL error: SQLCODE: -104, SQLSTATE: 42601的解决

     前一段时间在做一个项目时,遇到同样的代码在连接oracle的时候正常,在连接DB2数据库的时候出现异常不说,后台哗哗的报错.......直接上图吧:
[myProject] ERROR 2012-08-08 17:41:31,921 method:org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporter.java:72)
DB2 SQL error: SQLCODE: -104, SQLSTATE: 42601, SQLERRMC: );(+;(
[myProject] WARN 2012-08-08 17:41:31,921 method:org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporter.java:71)
SQL Error: -727, SQLState: 56098
[myProject] ERROR 2012-08-08 17:41:31,921 method:org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporter.java:72)
DB2 SQL error: SQLCODE: -727, SQLSTATE: 56098, SQLERRMC: 2;-104;42601;)|(+|(
[myProject] WARN 2012-08-08 17:41:31,921 method:org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporter.java:71)
SQL Error: -727, SQLState: 56098
[myProject] ERROR 2012-08-08 17:41:31,921 method:org.hibernate.util.JDBCExceptionReporter.logExceptions(JDBCExceptionReporter.java:72)
DB2 SQL error: SQLCODE: -727, SQLSTATE: 56098, SQLERRMC: 2;-104;42601;)|(+|(
org.hibernate.exception.GenericJDBCException: could not load an entity: [cn.test.oais.driver.database.EssTag#23111]
 at org.hibernate.exception.ErrorCodeConverter.handledNonSpecificException(ErrorCodeConverter.java:92)
 at org.hibernate.exception.ErrorCodeConverter.convert(ErrorCodeConverter.java:80)
 at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
 at org.hibernate.loader.Loader.loadEntity(Loader.java:1359)
 at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:116)
 at org.hibernate.loader.entity.EntityLoader.load(EntityLoader.java:101)
 at org.hibernate.loader.entity.BatchingEntityLoader.load(BatchingEntityLoader.java:82)
 at org.hibernate.persister.entity.BasicEntityPersister.load(BasicEntityPersister.java:2471)
 at org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:351)
 at org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:332)
 at org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:113)
 at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:151)[
 at org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:79)
 at org.hibernate.impl.SessionImpl.load(SessionImpl.java:603)
 at org.hibernate.impl.SessionImpl.load(SessionImpl.java:596)
 at cn.keyoflov.oais.driver._BaseRootDAO.load(_BaseRootDAO.java:744)
 at cn.test.oais.driver.database.impl.StructureDefineService.getEssTag(StructureDefineService.java:1288)
 at cn.test.oais.driver.database.impl.StructureDefineService.setTag(StructureDefineService.java:1644)
 at cn.test.oais.ipe.metadata.Tag.setTag(Tag.java:163)
 at cn.test.oais.webapp.action.manage.metadata.StructureAction.editTags(StructureAction.java:4257)
 at cn.test.oais.webapp.action.manage.metadata.StructureAction.saveGridData(StructureAction.java:4585)
 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.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:276)
 at cn.test.oais.webapp.struts.BaseAction._execute(BaseAction.java:181)
 at cn.test.oais.webapp.struts.BaseAction.execute(BaseAction.java:155)
 at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:421)
 at cn.test.oais.webapp.struts.RequestDynamicProcessor.process(RequestDynamicProcessor.java:114)
 at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1164)
 at org.apache.struts.action.ActionServlet.doPost(ActionServlet.java:415)
 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 cn.test.oais.webapp.filter.ActionFilter.doFilter(ActionFilter.java:88)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter.java:323)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at cn.test.oais.webapp.filter.GZIPFilter.doFilter(GZIPFilter.java:49)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.displaytag.filter.ResponseOverrideFilter.doFilter(ResponseOverrideFilter.java:125)
 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:75)
 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 com.opensymphony.clickstream.ClickstreamFilter.doFilter(ClickstreamFilter.java:42)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:174)
 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.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:292)
 at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:108)
 at org.acegisecurity.intercept.web.SecurityEnforcementFilter.doFilter(SecurityEnforcementFilter.java:197)
 at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303)
 at org.acegisecurity.providers.anonymous.AnonymousProcessingFilter.doFilter(AnonymousProcessingFilter.java:143)
 at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303)
 at org.acegisecurity.ui.rememberme.RememberMeProcessingFilter.doFilter(RememberMeProcessingFilter.java:154)
 at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303)
 at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:50)
 at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303)
 at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java:246)
 at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303)
 at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java:220)
 at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:303)
 at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java:173)
 at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java:120)
 at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
 at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
 at cn.test.oais.webapp.filter.SessionTimeoutFilter.doFilter(SessionTimeoutFilter.java:45)
 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: com.ibm.db2.jcc.c.SqlException: DB2 SQL error: SQLCODE: -104, SQLSTATE: 42601, SQLERRMC: );(+;(
 at com.ibm.db2.jcc.c.tf.e(tf.java:1680)
 at com.ibm.db2.jcc.c.tf.a(tf.java:1239)
 at com.ibm.db2.jcc.b.jb.h(jb.java:139)
 at com.ibm.db2.jcc.b.jb.a(jb.java:43)
 at com.ibm.db2.jcc.b.w.a(w.java:30)
 at com.ibm.db2.jcc.b.cc.f(cc.java:161)
 at com.ibm.db2.jcc.c.tf.n(tf.java:1219)
 at com.ibm.db2.jcc.c.uf.gb(uf.java:1816)
 at com.ibm.db2.jcc.c.uf.d(uf.java:2298)
 at com.ibm.db2.jcc.c.uf.X(uf.java:508)
 at com.ibm.db2.jcc.c.uf.executeQuery(uf.java:491)
 at com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.executeQuery(NewProxyPreparedStatement.java:76)
 at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java:120)
 at org.hibernate.loader.Loader.getResultSet(Loader.java:1272)
 at org.hibernate.loader.Loader.doQuery(Loader.java:391)
 at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:218)
 at org.hibernate.loader.Loader.loadEntity(Loader.java:1345)
 ... 86 more


查看报错的方法,发现里面代码是
 private EssTag getEssTag(EssStructure es, Field identifier, Session session)
   throws Exception {
  return (EssTag)
this.load(EssTag.class, this.getTagId(es, identifier,session), session);
 }
 
而报错的代码就是this.load(EssTag.class, this.getTagId(es, identifier,session), session)这一句.....
 
然后看一下我从网上查到的关于这个异常的解释
 org.hibernate.exception.GenericJDBCException: could not load an entity
 
(解释一下this.getTagId(es, identifier,session)取出来的就是一个long数据,值为23111。)
 有说是:
 1.普遍的人都会想到的,也就是大多数说的比较浅显的就是说
没有主键=23111的这条记录
于是找到EssTag.hbm.xml,找到其映射表名ess_tag,在PL/SQL
 下select * from ess_tag where id=23111 ,确实存在这个记录,这个因素可以排除。

 2.有说是JDBC驱动的问题,问题是驱动包版本过低,说换一个jar包问题迎刃而解,我不信,但还是查看了jar包版本,发现是最新的jar包。当然这其中也有说是hibernate的jar包的问题的,我更不信,况且如果是jar包的问题的话,
 oracle10G下可以正常跑程序啊,到了DB2数据库hibernate的jar包就不好使了,这个理由太扯了......

下面关注这个异常
Caused by: com.ibm.db2.jcc.c.SqlException: DB2 SQL error: SQLCODE: -104, SQLSTATE: 42601, SQLERRMC: );(+;(
参照http://www.ufaith.cn/read-65.html这个博客里面的关于DB2各代码的解释,不难看出是说sql有问题.....那么我就奇怪了,这明明就是利用hibernate的机制,直接load数据,传一个实体xx.class,数据主键id,session,就可以加载该条数据
(注意:前提是存在这个实体xx的映射文件,而且xx的映射文件一定要被装载,
在我的项目中是有EssTag.java,有EssTag.hbm.xml,而且applicationContext-resources.xml里面已经装载了映射文件。)

不过我还是比较相信确实sql有问题,于是在spring配置文件applicationContext-resources.xml里面将
              <!-- 输出所有SQL语句到控制台.取值 true | false  -->
             
<prop key="hibernate.show_sql">false</prop>
这一项的值改为true,于是所有的hql全都打印在控制台了,翻译成sql之后,把sql语句粘到oracle 的PL/SQL窗口可以顺利执行,粘到DB2的sql执行窗口,果然执行不了..........

     读者请理解一下这里.....我就不将我的真实sql粘过来了.........


     可以告诉大家的是,那个sql是很长的,使用的外连接,就是那种很传统的外连接写法,使用“(+)”来表示的那种,之前有听过说8i以下的版本不支持使用LEFT/RIGHT/FULL OUTER JOIN这种的外连接写法,因为使LEFT/RIGHT/FULL OUTER JOIN这种的外连接写法是比较高级的语法,而8i以下版本过低,解析不了这么高级的语法.......当然这是题外话,目的是想说这个sql在目前的oracle中(无论版本高低)是完全不可能出问题的......

     注意到这个报错信息SQLERRMC: );(+;(,注意到那几个奇怪的括号,于是我也是猜想,这个sql里面就外连接那里出现(+),难道是这个外连接导致的......于是把(+)这种的外连接翻译成LEFT OUTER JOIN 的这种写法,放到DB2中去执行,可以顺利执行......

     于是真相渐渐渐渐浮出水面,答案越来越清晰了.......

      DB2数据库不支持(+)这种的外连接的写法,支持LEFT OUTER JOIN 这种的外连接写法,但目前我还不太确信是不是所有DB2版本都不支持,我所知道的是8.x和9.X的版本目前都不支持(+)这种的外连接写法.......


读者不防自己尝试一下:
1. LEFT OUTER JOIN:左外关联
SELECT e.last_name, e.department_id, d.department_name
FROM employees e
LEFT OUTER JOIN departments d
ON (e.department_id = d.department_id);
(这种语法在DB2下能执行成功)

等价于
SELECT e.last_name, e.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id=d.department_id(+);
(这种语法在DB2下不能执行成功)

结果为:所有员工及对应部门的记录,包括没有对应部门编号department_id的员工记录。

2. RIGHT OUTER JOIN:右外关联
SELECT e.last_name, e.department_id, d.department_name
FROM employees e
RIGHT OUTER JOIN departments d
ON (e.department_id = d.department_id);
(这种语法在DB2下能执行成功)

等价于
SELECT e.last_name, e.department_id, d.department_name
FROM employees e, departments d
WHERE e.department_id(+)=d.department_id;

(这种语法在DB2下不能执行成功)

结果为:所有员工及对应部门的记录,包括没有任何员工的部门记录。


      但是又出现了一个比较纠结的问题,代码里面用的是hibernate的load...直接传的xx.class,id,session,那一堆hql是它自己内部拼出来的啊,我怎么样去改变它拼hql的语法啊,苦恼啊 ,苦恼....无尽的痛苦.......我遇到问题总是会自己先纠结上一阵的,自己能办到的事,坚决不求别人.....无奈之下,请教了一个DB2数据库高手吧.......

     我把我的研究成果告诉了他,他也确认了确实是外连接语法不正确导致的,他告诉我一个配置文件里面可以配置DB2外连接的语法,是使用left outer join ,还是(+).....
但是他也不记得在哪个配置文件里面配置的了............
于是我又开始苦恼啊 ,苦恼...................................................................................


      后来我发现是在applicationContext-resources.xml里面有个
<prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop>
这一句改成org.hibernate.dialect.DB2Dialect,于是重启服务以后,打印的hql果真不再使用(+)这种外连接了,使用正规的left outer join...... 控制台也不再报那两种奇怪的异常了....这说明定义hibernate的方言搞错了,于是hibernate翻译的hql造成了错误.........

    我的问题OK了!.不用改一行代码..........

    这个博客里面又比较详细的外连接语法的解释和举例:
   
http://anjian0802.blog.163.com/blog/static/47988453201031803577/


 

猜你喜欢

转载自linwei-211.iteye.com/blog/1666745