欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

com.sun.jdi.InvocationException不一定就是Hibernate的错

程序员文章站 2022-06-06 11:30:01
...

在HibernateDaoSupport的子类中有如下语句:List retValue=getHibernateTemplate().find("from ViewAttachAuth where 1=1"),其中ViewAttachAuth是自定义的实体对象,映射到数据库中的一个视图,按理说retValue应该是一个类型为ArrayList的对象,并且retValue中的每一个元素都是ViewAttachAuth对象,可是我在调试的时候发现返回对象的toString()方法得到的竟然是"com.sun.jdi.InvocationException occurred invoking method.",和普通的ArrayList对象的toString方法显然是不一样的,但是如果把它当做List接口来使用的话并不会出现问题,而如果System.out.println(retValue)的话则会出现java.lang.*Error堆栈溢出的错误,造成程序崩溃。综合网上的相关帖子以及自己使用Hibernate的经验初步断定这个现象和Hibernate的缓存以及延迟加载策略相关,不过ViewAttachAuth对应的视图中的记录并不多,只有四五条,在这么小的数据量的情况下Hibernate不至于启动二级缓存什么的吧,看来还得好好想想是怎么回事。

接下来的几分钟里我的脑海中一直出现一个字符串:toString,会不是toString这个方法本身的问题呢。按照这个思路我检查了我自己的实体类ViewAttachAuth,发现它的toString方法是下面这样定义的。

public String toString() {
	return org.apache.commons.lang.ObjectUtils.toString(this);
}

于是我尝试着改成下面这样: 

public String toString() {
		StringBuffer sb=new StringBuffer("[");
		sb.append("lsh="+getLsh()+",");
		sb.append("aname="+getAname()+",");
		sb.append("asize="+getAsize()+",");
		sb.append("description="+getDescription()+",");
		return sb.toString();
	}

很不幸(^_^),问题解决了。于是我忍不住想看看org.apache.commons.lang.ObjectUtils.toString(Object obj)的源码,看看里面究竟有什么魔力让我的程序崩溃,接下来的一幕让我惊呆了,下面是ObjectUtils中toString方法的源码片段:

public static String toString(Object obj) {
	return obj == null ? "" : obj.toString();
}

看到这里我最初的toString方法能引起程序崩溃也就不足为奇了:又是死循环!程序员的宿敌!