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

在HibernateDaoSupport的子类中有如下语句:ListretValue=getHibernateTemplate().find("from ViewAttachAuth where1=1"),其中ViewAttachAuth是自定义的实体对象,映射到数据库中的一个视图,按理说retValue应该是一个类型为ArrayList的对象,并且retValue中的每一个元素都是ViewAttachAuth对象,可是我在调试的时候发现返回对象的toString()方法得到的竟然是"com.sun.jdi.InvocationException occurred invokingmethod.",和普通的ArrayList对象的toString方法显然是不一样的,但是如果把它当做List接口来使用的话并不会出现问题,而如果System.out.println(retValue)的话则会出现java.lang.StackOverflowError堆栈溢出的错误,造成程序崩溃。综合网上的相关帖子以及自己使用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(Objectobj)的源码,看看里面究竟有什么魔力让我的程序崩溃,接下来的一幕让我惊呆了,下面是ObjectUtils中toString方法的源码片段:

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

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

相关推荐