项目中使用了Spring的OpenSessionInViewFilter,使得Hibernate的延时加载很方便,同时我也把DWR影射进取了,代码如下。
<filter></filter>
<filter-name></filter-name>hibernateFilter
<filter-class></filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
<init-param></init-param>
<param-name></param-name> singleSession
<param-value></param-value> true
<filter-mapping></filter-mapping>
<filter-name></filter-name>securityFilter
<url-pattern></url-pattern>/*
这样DWR就不会抱延时加载的错误了,但是它在把javaBean转换成JS的时候,调用了所有的Bean中的Get方法,这样Hibernate就把所有和这关联的属性都加载进来了,这样效率自然变低了,尤其是在加载Set的时候,一对多的时候,很慢,经常出错。,。。。。。。。。。
以上是我猜想的错误,就这样我想到修改源代码,个人适用的DWR版本是
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.6.5
Created-By: 1.5.0_07-87 ("Apple Computer, Inc.")
把其中的org.directwebremoting.convert.CollectionConverter文件下这个方法修改为
这样可以不加载Set了,其他属性还是加载,因为平时需要用到其他属性。
完成。。。。OK
public OutboundVariable convertOutbound(Object data, OutboundContext outctx) throws MarshallException
{
// Where we collect out converted children
Map ovs = new TreeMap();
// We need to do this before collecing the children to save recurrsion
ObjectOutboundVariable ov = new ObjectOutboundVariable(outctx);
outctx.put(data, ov);
try
{
Map properties = getPropertyMapFromObject(data, true, false);
for (Iterator it = properties.entrySet().iterator(); it.hasNext();)
{
Map.Entry entry = (Map.Entry) it.next();
String name = (String) entry.getKey();
Property property = (Property) entry.getValue();
Object value = property.getValue(data);
//如果为Set跳过------------------------------------------------
if(value!=null&&value.getClass()==org.hibernate.collection.PersistentSet.class){
continue;
}OutboundVariable nested = getConverterManager().convertOutbound(value, outctx);
ovs.put(name, nested);
}
}
catch (MarshallException ex)
{
throw ex;
}
catch (Exception ex)
{
throw new MarshallException(data.getClass(), ex);
}
ov.init(ovs, getJavascript());
return ov;
}