“阿飞哥”快来帮我看看这个hibernate得错误

情况说明:

      前台异步传入参数“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: