Search code examples
javajsonhibernatestruts2lazy-initialization

org.apache.struts2.json.JSONException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection


I am calling autocomplete from JSP url: "ProductByName". On response in console it is showing

POST http://localhost:8082/Store/SingleProduct 500 (Internal Server Error) 

In JSP:

 $(".name").autocomplete({
                    source: function(request, response) {
                        $.ajax({
                            url: "ProductByName",
                            dataType: "json",
                            data: {
                                str: request.term,
                                maxRows: 5
                            },...

In struts.xml:

<action name="ProductByName" class="iland.productdetails.ProductDetailsAction" method="fetchByProductName">
            <result type="json">
                <param name="includeProperties">productList\[\d+\]\.id,
                    productList\[\d+\]\.name,
                    productList\[\d+\]\.description
                </param>
                <param name="excludeNullProperties">true</param>
            </result>
        </action>

I want to fetch only few properties of productList

In Action class:

public class ProductDetailsAction extends ActionSupport {

private long id;

private String barCode;//bardoce

private String name;
private String desc;

private long quantity;
private float unitPrice;
private float sellingPrice;
private float totalSellingPrice;
private long clientId;
private ArrayList<BillDetails> BillList;
private Date startDate;
private Date endDate;
private int discountPercentage;
private Timestamp addDate;
private String dataStatus;
private ArrayList<ProductDetailsAction> productList;
private ArrayList<Product> productBillList;
public String fetchByProductName() {
         ProductDetailsBusiness pdb = new ProductDetailsBusiness();
          Map data = pdb.fetchByProductName(getName());
          setProductList((ArrayList) data.get("list"));
          return SUCCESS;
  }
   //other methods and getter and setter
    }   

I am getting following exception:

SEVERE: Exception occurred during processing request: org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: iland.hbm.Client.billDetailses, no session or session was closed
org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: iland.hbm.Client.billDetailses, no session or session was closed
    at org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:246)
    at org.apache.struts2.json.JSONWriter.processCustom(JSONWriter.java:178)
    at org.apache.struts2.json.JSONWriter.process(JSONWriter.java:168)
    at org.apache.struts2.json.JSONWriter.value(JSONWriter.java:134)
    at org.apache.struts2.json.JSONWriter.write(JSONWriter.java:102)
    at org.apache.struts2.json.JSONUtil.serialize(JSONUtil.java:116)
    at org.apache.struts2.json.JSONResult.createJSONString(JSONResult.java:197)
    at org.apache.struts2.json.JSONResult.execute(JSONResult.java:171)
    at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:371)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:275)
    at org.apache.struts2.interceptor.debugging.DebuggingInterceptor.intercept(DebuggingInterceptor.java:256)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:167)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:265)
    at org.apache.struts2.interceptor.validation.AnnotationValidationInterceptor.doIntercept(AnnotationValidationInterceptor.java:68)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:239)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:239)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:252)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ChainingInterceptor.intercept(ChainingInterceptor.java:145)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
    at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:161)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.AliasInterceptor.intercept(AliasInterceptor.java:193)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
    at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:246)
    at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
    at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:563)
    at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:77)
    at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:744)
Caused by: org.apache.struts2.json.JSONException: org.apache.struts2.json.JSONException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: iland.hbm.Client.billDetailses, no session or session was closed
    at org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:246)
    at org.apache.struts2.json.JSONWriter.processCustom(JSONWriter.java:178)
    at org.apache.struts2.json.JSONWriter.process(JSONWriter.java:168)
    at org.apache.struts2.json.JSONWriter.value(JSONWriter.java:134)
    at org.apache.struts2.json.JSONWriter.add(JSONWriter.java:390)
    at org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:231)
    ... 71 more
Caused by: org.apache.struts2.json.JSONException: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: iland.hbm.Client.billDetailses, no session or session was closed
    at org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:246)
    at org.apache.struts2.json.JSONWriter.processCustom(JSONWriter.java:178)
    at org.apache.struts2.json.JSONWriter.process(JSONWriter.java:168)
    at org.apache.struts2.json.JSONWriter.value(JSONWriter.java:134)
    at org.apache.struts2.json.JSONWriter.add(JSONWriter.java:390)
    at org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:231)
    ... 76 more
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: iland.hbm.Client.billDetailses, no session or session was closed
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
    at org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
    at org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
    at org.hibernate.collection.AbstractPersistentCollection.read(AbstractPersistentCollection.java:111)
    at org.hibernate.collection.PersistentSet.equals(PersistentSet.java:429)
    at java.util.Vector.indexOf(Vector.java:408)
    at java.util.Vector.contains(Vector.java:367)
    at org.apache.struts2.json.JSONWriter.value(JSONWriter.java:117)
    at org.apache.struts2.json.JSONWriter.add(JSONWriter.java:390)
    at org.apache.struts2.json.JSONWriter.bean(JSONWriter.java:231)
    ... 81 more 

Edit:

fetchByProductName(getName()); method contains only Jdbc code. Then why Hibernate Errorrs??

I am fetching date from database and also printing on console. before success I gave System.out.println(In action); this is aslo printing properly It doesnt have to access data from database then why failed to lazily initialize a collection of XXX How to resolve this.

Edit:

 public class ProductDetailsBusiness {

ProductDetailsAction pda = null;
PreparedStatement ps = null;
ResultSet rs = null, res = null;
Connection con = null;
String status = null;
ArrayList<ProductDetailsAction> ar = null;

public Map fetchByProductName(String name, long cid) {
        System.out.println(" ProductBusiness fetchByProductName()");
        status = "success";
        System.out.println("Name is " + name);

        ar = new ArrayList();
        con = ConnectionFactory.getConnection();

        try {
            String query = "select * from product "
                    + "where status=? and cid=? "
                    + "order by add_date";

            ps = con.prepareStatement(query);
            ps.setString(1, "active");
             ps.setLong(2, cid);
            System.out.println("Before execution");
            res = ps.executeQuery();

            System.out.println("Details are");
            while (res.next()) {
                pda = new ProductDetailsAction();
                long id1 = res.getLong("id");
                String barCode = res.getString("barcode");
                String name1 = res.getString("name");
                String desc = res.getString("description");
                long quntity = res.getLong("quntity");
                float unit_price = res.getLong("unit_price");
                float selling_price = res.getLong("selling_price");
                int discount_percent = res.getInt("discount_percent");
                pda.setId(id1);
                pda.setBarCode(barCode);
                pda.setName(name1);
                pda.setDesc(desc);
                pda.setQuantity(quntity);
                pda.setUnitPrice(unit_price);
                pda.setSellingPrice(selling_price);
                pda.setDiscountPercentage(discount_percent);
                System.out.println("id "+id1+" name "+name1+" "+desc);
                ar.add(pda);
            }

            con.close();
        } catch (SQLException s) {
            status = "failure";
            System.out.println("SQL code does not execute." + s);
        } finally {
            try {
                if (con != null) {
                    con.close();
                }
            } catch (SQLException sqe) {
                status = "failure";
                System.out.println("SQLException " + sqe);
            }
        }
        Map m = new HashMap();
        m.put("status", status);
        m.put("list", ar);
        return m;
    }
      //other methods
    }

Also updated action class Please also see it


Solution

  • The serialization process to JSON is controlled by JSON result, which is a part of the JSON plugin that you used in your project. And you already know that to limit properties used by serializer you should use includeProperties of the json result. There's also root property that you should examine. If not specified the json result uses by default the top object of the value stack. If your action is model driven then model overrides action. So, the regexes you used in the includeProperties apply to the model object, and serializer which is JSONWriter uses BeanInfo to extract properties of the bean. First, these properties are checked for existence of @JSON annotation and if it has serialize=false, then it's skipped, otherwise it's included. This way you can control the serialization process via putting annotations on the properties that you won't serialize to JSON such as @OneToMany properties, etc. Then includeProperties or excludeProperties are checked if they are not empty. At this time you should acknowledge that if you don't have properties that matches to the patterns specified then them won't be serialized. So, lets move to LazyInitializationException, as I said if you have @JSON annotation ever in the model hierarchy you should put serialize=false inside it because by default it's true.

    @JSON(serialize=false)
    public Object getBillDetailses(){ return billDetailses; }
    

    You said your productList in the action class, then you should configure the result

    <!-- Result config -->
    <result type="json">
      <param name="includeProperties">
        ^productList\[\d+\]\.id,
        ^productList\[\d+\]\.name,
        ^productList\[\d+\]\.description
      </param>
      <param name="root">
        #action
      </param>
    </result>   
    

    Note, that ^ stands for beginning the expression, so only action properties will be included.