毕业设计之错误集锦(四)

1.org.hibernate.MappingException: Dialect does not support identity key generation

       今天遇到的这个错误可谓奇葩,严重阻碍了我的进度,导致昨天没有前进一步,这个错误其实很好理解的,但是不等于很好解决,一般出现这个问题原因有以下几点:第一,Dialect写错了,与数据库不匹配;第二:数据库不支持identity类型的主键设置,比如oracle,即在你的程序总存在identity类型的主键设置。而我用的正是oracle数据库,但是我找遍了workspace都没与找到一个identity字符串,而我的主键设置都是assigned的,况且再另一张表上我是成功了,而这一张表与成功的那张表的唯一区别就是存在外键,涉及到多表查询。好吧,那就debug一下外键吧,

毕业设计之错误集锦(四)_第1张图片

    原来hibernate压根就没有去关联插叙,外键表对象是空的,检查了一下hibernate的配置文件,一切正常,没发现错误,好的,错误有可能是关联出现的,与此同时还出现其他的错误,如下

   com.googlecode.jsonplugin.JSONException: java.lang.reflect.InvocationTargetException

 Class com.googlecode.jsonplugin.JSONWriter can not access a member of class org.springframework.aop.TruePointcut with modifiers "public"



     这个错误就是json数据出错,出现这个问题是某属性通过串行化json数据异常,意思是这样的,struts2的action里面的数据转换成json数据时是将提供了getter的属性都统统串行化输出JSON到客户端。有的时候,很多属性并不一定要串行化成json数据。比如:使用的spring注入属性,也就是提供了getter和setter!所以解决这个异常方法就是在不需要串行化的属性的getter前加上annotation,就是@JSON(serialize=false),或者直接去掉不需要的getter方法。

      这样搞完之后我重启tomcat服务,浏览器,myeclipse,但是结果还是同样的错,跟没搞过一样,这时候已经凌晨2点了,困得不行了,就睡了,今天早上起来打开电脑运行,奇迹出现了,居然这个错误不见了,虽说页面还是没有查询出数据,哈哈,看样子昨天晚上电脑缓存太严重了,重启才是王道!

    前面说过,只要涉及到外键就出错,现在去通过外键查询数据时,依然出错,如下:

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

原因:hibernate3 many-to-one的默认选项是 lazy = "proxy"(向我这样的菜鸟可以认为是true)
解决方法<many-to-one>  & <set> 中设置 lazy="false"或者fetch=“join”或者OpenSessionInViewFilter(这个是大家都推荐的,既可以延迟加载提高效率,也可以解决问题)再或者在spring中进行事务控制也可以。

      延迟加载,顾名思义就是用到的时候再去加载,在我当前的这个系统环境下可以理解为当ExtJs界面需要外键中的值时,再通过ajax去请求加载外键表中的数值,但是此时session对象已经关闭,因此次才会出现上面的错误。但是。。。我去年做的时候没有这回事啊,难道是今年因为加入了spring?哈哈,看样子真是猜对了,如下这段话是从网上找到的“在hibernate 的one-to-many,many-to-one,many-to-many中,为了效率的提高,我们一般都采用lazy机制,但使用spring的getHibernateTemplate().save(Object)时,HibernateTemplate试图每次在execute之前去获得Session,执行完就力争关闭Session 。也就是说Hibernate的Lazy初始化1:n关系时,你必须保证是在同一个Session内部使用这个关系集合,不然Hiernate将抛出Failed to lazily initialize a collection - no session or session was closed的例外。”同一个session内部?难道我的不是同一个session?想一想。。。这不是废话吗,既然session已经关闭了,再去访问肯定需要new一个session,能是同一个吗?

     哈哈,这个问题终于解决了,耗了一个下午和晚上,可能从上面的解决过程来看,有点乱,确实这几个错误有点无厘头,但是仔细分析之后你会发现,一切的根源就是那个外键,抓住这个就抓住了问题的本质了,也就事半功倍了,有时候系统自动的报错会让人误入歧途的,这就需要自己去甄别了。另外,好了这么长时间,得出几点教训:第一:借助各种debug工具主动去找错,不要光等着浏览器或者myeclipse报错;第二:一般一次报错会有上百行之多,如何从中找到有用的信息至关重要;第三:用互联网的时候要讲究策略,感觉先用google后用baidu比较好,我之前用反了,浪费了好多时间;第四:在穷途末路的时候可以考虑重启一下电脑,会有意想不到的收获;

2.java.lang.NullPointerException    java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1235)    java.text.DateFormat.parse(DateFormat.java:335)

  很明显,是时间解析有误,第一次:我把所有的时间格式都统一成了“Y年m月d日”,但是还是出错;第二次:debug一下,如下图

毕业设计之错误集锦(四)_第2张图片

这个有点出乎我的意料,1):明明是date类型的数据怎么就变成了timestamp呢?2):时间显示的时候没有时分秒的,在这里怎么就有了?基于以上两点,

第三次:解析日期的时候加上时分秒,但是........

第四次:忽然发现我误入歧途了,人家明明已经说得很清楚了,空指针错误,你还在解析个毛啊,结果打印了一下value,确实是null,唉,惯性思维害死人啊,终于步入正途了,不过还是借此了解了一下前两个问题,这是网上的一段总结,写的不错“众所周知Oralce的日期类型有很多种,Date ,Timestamp等。其中Date类型对用的是java.sql.Date类型,Timestamp对用的是java.sql.Timestamp类型。这两个类型均继承自java.util.Date,其中java.sql.Date是没有时分秒的,大家可以查看一下javaApi”我可以说我在API中我没查到

第五次:用firebug了一下,发现在js页面上value是拿到值了,而在传到后台的过程中丢失,什么情况?这么诡异?在网络中经常说丢包丢包,但是在java中倒是第一次见哈,既然无法逃避,那就只能面对了,好了,来分析一下,

第一:丢失值时出现在传值的过程中,也就是说从前台的接口中送出的值后台没有收到,或者是拒绝接受,只有这两种情况。

第二:除了日期类型的,其他类型的都成功传值,而且所有类型用的都是同一通道,同一接口,同一载体这两点足以说明是后台拒绝接受,而且理由就是类型不符合,哈哈豁然开朗,既然是类型不符合,那就转换一下让他符合好了,js页面要传值之前:

if(field == "setup") {
			value = Ext.util.Format.date(value,"Y年m月d日");
		}
OK测试.....成功!哈哈,看来我得分析推理能力还是蛮不错的嘛!
不对,慢着,为什么系统显示更新成功,hibernate的update语句都打印出来了,可是数据库中没有更新,什么情况?更新不同步,好吧,现在看来,网上都是说没有提交事务,但是有spring的话,就不需要hibernate亲自提交事务了,更何况其他类型的都可以更新成功,只有date类型才会出现这种问题,所以不太可能是事务没提交这种情况了,一次次的尝试之后发现了一个有趣的现象,只要deployed整个工程,数据库就会马上更新成最近的日期,嗯?真是奇葩,难道这预示着什么吗?想想....热部署!这是能想到的最接近的答案了,tomcat在热部署的时候还在处理系统的请求,至于严谨的论证侧没有,上网查了好久,都是只有方法,没有原理,顶多就是tomcat的原理而已,不管了,总归有spring的事务没有提交的可能性,那就试试吧,不管这个过程也不是一帆风顺的。
tx:annotation-driven is not bound
没有绑定tx,通俗一点就是没有导入tx的包,如下:
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
	http://www.springframework.org/schema/tx 
	http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
Pointcut is malformed: Pointcut is not well-formed: expecting 'name pattern' at character position 29
 execution(*com.shiep.dao.*.*(..)) 
这个错误是目前为止让人最无语的错误,竟然是由于execution中*和后面的com之间有一个空格,唉,这种错误碰到就只有认命的份了。
 cvc-complex-type.3.2.2:Attribute 'transacton-manager' is not allowed to appear in element 'tx:advice'.

这个错误更坑爹,居然是关键字写错的原因,也好以后只要碰到is not allowed to appear in element '之类的,十有八九就是关键字写错的原因了
好了,错误终于搞完了,spring配置也完成了,如下,也为以后做个备份哈
	<!-- 声明一个 Hibernate 3 的事务管理器供代理类自动管理事务用 -->
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory">
			<ref bean="sessionFactory" />
		</property>
	</bean>
	<!--配置事务传播特性-->
	<tx:advice id="txAdvice" transaction-manager = "transactionManager">
		<tx:attributes>
			<tx:method name="*" propagation="REQUIRED"/>
		</tx:attributes>
	</tx:advice>
	<!-- 指明哪些类要使用事务-->
	<aop:config>
		<aop:pointcut id="allmethod" expression="execution(* com.shiep.dao.*.*(..))" />
		<aop:advisor advice-ref="txAdvice" pointcut-ref="allmethod"/>
	</aop:config>
   不过这里需要注意的一点就是spring的事务代理是建立在接口的基础之上的,因此使用事务的只可能是接口,在这里我们可以看到,使用到了spring的声明式事务管理,实现了事务管理与业务代码的分离,配置文件中出现了关键字aop,相信大家对它不陌生,这是面向切面编程的意思,因为事务管理本身就是一个典型的横切逻辑,与核心业务关系不大,但是却需要。关于spring的事务配置,这里有一篇文章写得很好,很全面:点击打开链接
   测试,系统更新成功,数据库...更新...成功了!哈哈,看样子还真是spring事务没有控制到这里
    ......
   嗯,一不小心发现已经凌晨3点了,再不睡就天亮了,走起,秒睡!










   

你可能感兴趣的:(spring,oracle,Hibernate,毕业设计)