-1

I am working on a project with the combination of struts+spring+hibernate. Hibernate is a framework that i like most but i stuck to a problem Lazy Initialization Exception. I have to solve this but what i don't want to loose is

  • I cant loose DTO from my project that helps to communicate between the layers.
  • I don't want to access persistence object to service layer.
  • I don't want to loos Utility class that translate the Persistence object to data transfer object.

Here are the coding implementation that i have done. I am calling this method on the service layer

sectionsservice.getAllSections();

The DAO Implementations are like this

public List<SectionsTO> getAllSections() {
    List<SectionsTO> sectionsto_list=new ArrayList<SectionsTO>();
    List<Sections> sections_list=htemp.loadAll(Sections.class);

    try {
        SessionFactory factory=HibernateUtil.getSessionFactory();
        Session session=factory.openSession();
        Transaction tx=session.beginTransaction();
            Query qry=session.createQuery("from Sections sections");
            List list=qry.list();
            Iterator it=list.iterator();
            while(it.hasNext()) {
                Sections sections=(Sections)it.next();
                SectionsTO sectionsto=**PropertyUtil**.getSectionsTOFromSections(sections);
                sectionsto_list.add(sectionsto);
            }
        tx.commit();
        session.close();
        factory.close();
    }
    catch(Exception e) {
        e.printStackTrace();
    }
    return sectionsto_list;
}

here is the PropertyUtil class implementation

public static SectionsTO getSectionsTOFromSections(Sections sections) {
    SectionsTO sectionsto=new SectionsTO();
    sectionsto.setSection_id(sections.getSection_id());
    sectionsto.setSection_name(sections.getSection_name());
    sectionsto.setSection_desc(sections.getSection_desc());
    sectionsto.setThreads(sections.getThreads());
    sectionsto.setPosts(sections.getPosts());
    sectionsto.setLast_post(sections.getLast_post());
    sectionsto.setLast_post_by(PropertyUtil.getMembersTOFromMembers(sections.getLast_post_by()));
    sectionsto.setQuestion_id(sections.getQuestion_id());
    Set<Questions> questions_set=sections.getQuestions_set();
    Set<QuestionsTO> questions_set_to=new HashSet<QuestionsTO>();
    Iterator<Questions> it=questions_set.iterator();
    while(it.hasNext()) {
        QuestionsTO questionsto=PropertyUtil.getQuestionsTOFromQuestions(it.next());
        questions_set_to.add(questionsto);
    }
    return sectionsto;
}

Here is the stacktrace of the error what i m getting

 SEVERE: Servlet.service() for servlet [action] in context with path [/TechForum] threw exception [org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.cac.hibernate.Sections.questions_set, no session or session was closed] with root cause
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.cac.hibernate.Sections.questions_set, 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.toString(PersistentSet.java:309)
    at java.lang.String.valueOf(Unknown Source)
    at java.io.PrintStream.println(Unknown Source)
    at org.apache.tomcat.util.log.SystemLogHandler.println(SystemLogHandler.java:269)
    at com.cac.dao.HibernateSectionsDAO.getAllSections(HibernateSectionsDAO.java:93)
    at com.cac.service.SectionsServiceImpl.getAllSections(SectionsServiceImpl.java:48)
    at com.cac.struts.RegisterAction.fetch_sections(RegisterAction.java:107)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.apache.struts.actions.DispatchAction.dispatchMethod(DispatchAction.java:269)
    at org.apache.struts.actions.DispatchAction.execute(DispatchAction.java:170)
    at org.springframework.web.struts.DelegatingActionProxy.execute(DelegatingActionProxy.java:113)
    at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:425)
    at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:228)
    at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1913)
    at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:449)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:306)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:198)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:244)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:161)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:108)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:379)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:243)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:259)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:281)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

The persistance class(Section ) and transfer Objects(SectionsTO) are like this sections

 private int section_id;
    private String section_name;
    private String section_desc;
    private int threads;
    private int posts;
    private String last_post;
    private Members last_post_by;
    private Date last_post_date;
    private int question_id;
    private Set<Questions> questions_set;
    //setter
    //getter

SectionsTO

private int section_id;
    private String section_name;
    private String section_desc;
    private int threads;
    private int posts;
    private String last_post;
    private MembersTO last_post_by;
    private Date last_post_date;
    private int question_id;
    private Set<QuestionsTO> questionsto_set;
    //setter
    //getter

The thing is that if i do lazy="true" on the collection i will get a lazy initialization exception while if i do lazy="false" it will eagerly load all the tables due to propertyutil class implementation. From last 48 hours i stuck to that. So please suggest me some optimized way to go.

yshavit
  • 42,327
  • 7
  • 87
  • 124
user528050
  • 157
  • 2
  • 4
  • 21
  • Not sure if that's what you want, but you might find http://stackoverflow.com/questions/1600215/implementing-result-paging-in-hibernate-getting-total-number-of-rows interesting – Marcin Łoś Sep 07 '13 at 02:10
  • @MarcinŁoś No i don't want to perform pagination. It's about coading design where i stuck with lazy initialization Exception. – user528050 Sep 07 '13 at 02:15
  • On what line do you get the lazy initialization exception? Can you post the stack trace? Can you also post the source code for both `Sections` and `SectionsTO`? – David Levesque Sep 07 '13 at 02:20
  • 1
    Can you identify HibernateSectionsDAO line 93? – samlewis Sep 07 '13 at 02:39
  • @samlewis As you can see my PropertyUil class that will initialize all the persistence class in order to translate persistence object to data transfer object. Have i eriteen correct PropertyUtil class ? – user528050 Sep 07 '13 at 02:42
  • 1
    What is this line doing? `List sections_list=htemp.loadAll(Sections.class);` – David Levesque Sep 07 '13 at 02:47
  • @DavidLevesque It will load all the type of sections in a forum.But due to lazy="false" it will load the all the questions also. That is what i don't want. – user528050 Sep 07 '13 at 03:01
  • But the variable `sections_list` is not used anywhere... – David Levesque Sep 07 '13 at 03:03
  • See http://stackoverflow.com/questions/15427602/lazy-loading-of-the-content/15428167#15428167 – Roman C Sep 07 '13 at 08:37

1 Answers1

1

As you want to go with lazy="true", you can solve this by using runtime association fetching strategies. Hibernate lets you specify a default fetching strategy in the mapping file, which can be overridden at runtime in code.

Define lazy="true" in your mapping, which will result in lazy fetching of the associated object or collection. Now wherever you want the associated object or collection to be fetched eagerly, override this default fetching strategy as below:

In HQL, an association can be eagerly fetched by an outer join using the fetch keyword in the from clause:

from Sections sections left join fetch sections.questions_set

The same thing can be done using the Criteria API:

session.createCriteria(Sections.class)
.setFetchMode("questions_set", FetchMode.EAGER).list();

When executed, both of these queries will return a list of Section instances, with their question_set collections fully initialized.

With these fetching strategies the associations will not be loaded eagerly at all times, but you can (re)define the strategies to be used at runtime.

Debojit Saikia
  • 10,532
  • 3
  • 35
  • 46