情况说明:
前台异步传入参数“speakId”,action获取speakId后(业务逻辑暂且在action中处理),到comment表中查找外键为speakId的comment们,保存在commList中,commList作为json类型返回前台(?)。
ajax代码:
... $.ajax({ type : "POST", url : "showComment.action", data : { speakId : speakId }, success : callbackShowComm, dataType : "json", error : function (data, status, e){ alert(e); history.go(0);} });//callbackShowComm function callbackShowComm(backData,status){ if(status == "success"){ if(backData != null){ //test alert(backData);//此处没有返回值 }//end backData }else{ alert(status); } }
...
action代码:
package com.shaiyaya.action; import java.util.*; import java.text.SimpleDateFormat; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import org.apache.struts2.interceptor.ServletRequestAware; import org.hibernate.Session; import org.hibernate.Transaction; import org.hibernate.Query; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.ActionSupport; import com.shaiyaya.constant.ConstantVariable; import com.shaiyaya.dao.User; import com.shaiyaya.dao.Speak; import com.shaiyaya.dao.Comment; import com.shaiyaya.orm.HibernateSessionFactory; import com.shaiyaya.service.CommentService; public class CommentAction extends ActionSupport implements ServletRequestAware { private HttpServletRequest request; public void setServletRequest(HttpServletRequest request) { this.request = request; } private List<Comment> commList = new ArrayList<Comment>();//包含查看相应speakID对应的评论的Comment信息 public void setCommList(ArrayList<Comment> commList){ this.commList = commList; } public List<Comment> getCommList(){ return this.commList; } /** * 异步获取speakID对应的comment信息 * @return */ public String showComment(){ int speakId = Integer.valueOf( request.getParameter("speakId") ); if(speakId <1){ return "errorSpeakId"; } Session session = HibernateSessionFactory.getSession(); Transaction tran = session.beginTransaction(); String sql = "from Comment as c where c.speak =" +speakId+ "order by commentId desc" ; Query query = session.createQuery(sql); commList = query.list();//说明:要是List commList = commentservice.findCommentBySpeakId(speakId);则没有报错了 // commList = commentservice.findCommentBySpeakId(speakId); tran.commit(); session.close(); request.setAttribute("commList", commList); System.out.println("commListSize:"+commList.size()); return "success"; } }//end class
struts-xml配置文件:
... <package name="ajax-comment" extends="json-default"> <!-- 查看speak对应的评论异步请求 --> <action name="showComment" class="com.shaiyaya.action.CommentAction" method="showComment"> <result name="success" type="json"> <param name="root">commList</param> </result> <result name="errorSpeakId" type="json"> <param name="root">commList</param> </result> </action> </package> ...
运行结果及报错:
Hibernate: select comment0_.comment_id as comment1_23_, comment0_.speak_id as speak2_23_, comment0_.user_id as user3_23_, comment0_.content as content23_, comment0_.create_time as create5_23_ from shaiyaya.comment comment0_ where comment0_.speak_id=112 order by comment0_.comment_id desc Hibernate: select speak0_.speak_id as speak1_5_0_, speak0_.user_id as user2_5_0_, speak0_.content as content5_0_, speak0_.create_time as create4_5_0_, speak0_.last_comm_time as last5_5_0_, speak0_.cate_flag as cate6_5_0_, speak0_.attachment_flag as attachment7_5_0_, speak0_.comment_sum as comment8_5_0_, speak0_.love_sum as love9_5_0_, speak0_.forward_sum as forward10_5_0_ from shaiyaya.speak speak0_ where speak0_.speak_id=? Hibernate: select user0_.user_id as user1_15_0_, user0_.user_nick as user2_15_0_, user0_.real_name as real3_15_0_, user0_.password as password15_0_, user0_.user_ip as user5_15_0_, user0_.address as address15_0_, user0_.user_sex as user7_15_0_, user0_.create_time as create8_15_0_, user0_.update_time as update9_15_0_, user0_.user_email as user10_15_0_, user0_.user_intro as user11_15_0_, user0_.user_status as user12_15_0_, user0_.login_sum as login13_15_0_, user0_.last_login_time as last14_15_0_, user0_.role as role15_0_, user0_.memo as memo15_0_ from shaiyaya.user user0_ where user0_.user_id=? commListSize:2 [ERROR] 10-19-19:12:23 org.hibernate.LazyInitializationException.<init>(LazyInitializationException.java:19) [thread:http-80-2] [messgage:failed to lazily initialize a collection of role: com.shaiyaya.dao.Speak.comments, no session or session was closed] org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.shaiyaya.dao.Speak.comments, no session or session was closed at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:358) at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:350) at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:343) at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:86) at org.hibernate.collection.PersistentSet.equals(PersistentSet.java:350) at java.util.Vector.indexOf(Vector.java:361) at java.util.Vector.contains(Vector.java:320) at com.googlecode.jsonplugin.JSONWriter.value(JSONWriter.java:110) at com.googlecode.jsonplugin.JSONWriter.add(JSONWriter.java:324) at com.googlecode.jsonplugin.JSONWriter.bean(JSONWriter.java:225) at com.googlecode.jsonplugin.JSONWriter.process(JSONWriter.java:161) at com.googlecode.jsonplugin.JSONWriter.value(JSONWriter.java:127) at com.googlecode.jsonplugin.JSONWriter.add(JSONWriter.java:324) at com.googlecode.jsonplugin.JSONWriter.bean(JSONWriter.java:225) at com.googlecode.jsonplugin.JSONWriter.process(JSONWriter.java:161) at com.googlecode.jsonplugin.JSONWriter.value(JSONWriter.java:127) at com.googlecode.jsonplugin.JSONWriter.array(JSONWriter.java:416) at com.googlecode.jsonplugin.JSONWriter.process(JSONWriter.java:151) at com.googlecode.jsonplugin.JSONWriter.value(JSONWriter.java:127) at com.googlecode.jsonplugin.JSONWriter.write(JSONWriter.java:95) at com.googlecode.jsonplugin.JSONUtil.serialize(JSONUtil.java:98) at com.googlecode.jsonplugin.JSONResult.execute(JSONResult.java:179) at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:361) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:265) at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:163) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:249) at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:122) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:195) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:148) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:93) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:235) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:89) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:128) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at org.apache.struts2.interceptor.ProfilingActivationInterceptor.intercept(ProfilingActivationInterceptor.java:104) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:267) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:126) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:138) at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:87) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:148) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:128) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:176) at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:236) at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:52) at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:468) at org.apache.struts2.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java:395) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) at org.apache.struts2.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java:102) 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:127) 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:298) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:852) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:619)
前面action里面的commList = query.list改为List commList = commentservice.findCommentBySpeakId(speakId);则没有报错,不过这样就没有往前台传值了,ajax的success函数中的backData是没有值的。
comment表有两个外键speakId和userId 在comment.hbm.xml已经设置了lazy=“false”,代码如下:
<hibernate-mapping> <class name="com.shaiyaya.dao.Comment" table="comment" catalog="shaiyaya"> <id name="commentId" type="java.lang.Integer"> <column name="comment_id" /> <generator class="native" /> </id> <many-to-one name="speak" class="com.shaiyaya.dao.Speak" fetch="select" lazy="false"> <column name="speak_id" /> </many-to-one> <many-to-one name="user" class="com.shaiyaya.dao.User" fetch="select" lazy="false"> <column name="user_id" /> </many-to-one> <property name="content" type="java.lang.String"> <column name="content" /> </property> <property name="createTime" type="java.util.Date"> <column name="create_time" length="19" /> </property> </class> </hibernate-mapping>
这是什么原因呢?或者我要怎样才能把commList即comment对象的List传给前台呢?
我看了一下 你的Speak这个对象里面有comments 这个集合对象 是吧。
你的情况我做两个回答吧,
1,针对为什么你用方法内的list,就不能给你生成json了,是因为,给你生成json的包,只针对在struts2环境内的对象(外面在action定义的是属于struts2环境管制的)。
2,json的的插件给你生成json的时候,把你Speak的里面的集合也一并生成了,而你的comments并没有设置成lazy=false的,所以这个时候延迟加载失败了。(但是即使你设置成lazy=false也是不对的,因为这样会循环下去给你生成json)
1,首先确定在action里面的时候commList 是有值的。
2,你的action里面并没有把commList 转化成json啊,你必须得转,前台才能认识你的json啊。
3,你的ajax操作的
if(status == "success"){
这个判断可以去掉,因为只有成功后才会调用
callbackShowComm这个函数。
应该是给你转化成json的时候的错误,
给你转化成json的时候,你的list的对象里面应该是还有集合对象。
你这样,你先把json生成的 只给你生成基本属性,比如 Integer,String的。
这个你应该可以设置吧
jsonplugin的包我没有用过,但是一般这种第三方插件都可以设置的。
[quote]是不是循环生成json的时候还要用用到speak,但是此时session已经关闭了?怎么做呢? [/quote]
说对了一办。
json生成的时候给你生成speak,这一步不会报错,但是此时发觉你的speak里面有个comments的集合,这个时候会调用你的get方法,由于你的comments没有设置成lazy=false,所以延迟加载的时候报session已经关闭。
所以说 一般json的插件都会有这样一个设置:对普通对象做json转换。
比如我常用的jsonlib里面就会设置onlyBaseProperty的设置,这样就不会有问题了。
同学,是你的hibernate lazy属性没设置好吧。
10-19-19:12:23 org.hibernate.LazyInitializationException.(LazyInitializationException.java:19) [messgage:failed to lazily initialize a collection of role: com.shaiyaya.dao.Speak.comments, no session or session was closed]
comments里面的role在hibernate xml里面设置成lazy吧 或者在HQL里用join fetch
comments里没有role外键的话估计是user的表里和role有关的外键没设lazy
应该是可以在get方法上面设置
@Json(serialize=false).那么这个属性就不会被转化了。 :wink: