openSession(), getCurrentSession(), beginTransaction(), lazy load
<p>I have a simple java web application that receive some information from database and display that information in web browser. Hibernate is used to interact with database in servlets and jsp files. All work as I want, but I don't understand some things. </p>

<p>Database is simple - 2 tables: Question and Answer. Relationship between tables is one-to-many: one Question can have many Answers.</p>

<p>This is code of java classes Question and Answer:</p>

<p><strong>Question.java</strong></p>

<pre><code>package app;

import java.util.Set;

public class Question {
    Long id = null;
    String text = "";
    Set&lt;Answer&gt; answers = null;

    public Question() {        
    }    

    public void setId(Long id) {
        this.id = id;
    }
    public void setText(String text) {
        this.text = text;
    }
    public void setAnswers(Set&lt;Answer&gt; answers) {
        this.answers = answers;
    }
    public Long getId() {
        return id;
    }
    public String getText() {
        return text;
    }
    public Set&lt;Answer&gt; getAnswers() {
        return answers;
    }
}
</code></pre>

<p><strong>Answer.java</strong></p>

<pre><code>package app;

public class Answer {
    Long id = null;    
    String text = "";
    Question question = null;

    public Answer() {
    }
    public void setId(Long id) {
        this.id = id;        
    }
    public void setText(String text) {
        this.text = text;
    }
    public void setQuestion(Question question) {
        this.question = question;
    }    
    public Long getId() {
        return id;
    }
    public String getText() {
        return text;
    }
    public Question getQuestion() {
        return question;
    } 
}
</code></pre>

<p>And this is configuration of Hibernate:</p>

<p><strong>hibernate.cfg.xml</strong></p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"&gt;
&lt;hibernate-configuration&gt;
  &lt;session-factory&gt;
    &lt;property name="hibernate.connection.driver_class"&gt;com.microsoft.sqlserver.jdbc.SQLServerDriver&lt;/property&gt;
    &lt;property name="hibernate.connection.url"&gt;jdbc:sqlserver://localhost;databaseName=Test&lt;/property&gt;
    &lt;property name="hibernate.connection.username"&gt;sa&lt;/property&gt;
    &lt;property name="hibernate.connection.password"&gt;password&lt;/property&gt;

    &lt;property name="hibernate.current_session_context_class"&gt;thread&lt;/property&gt;

    &lt;mapping resource="question.hbm.xml"/&gt;
    &lt;mapping resource="answer.hbm.xml"/&gt;
  &lt;/session-factory&gt;
&lt;/hibernate-configuration&gt;
</code></pre>

<p><strong>question.hbm.xml</strong></p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&gt;
&lt;hibernate-mapping package="app"&gt;
    &lt;class name="app.Question" table="Question"&gt;
        &lt;id column="id" name="id" type="java.lang.Long"&gt;
            &lt;generator class="native"/&gt;
        &lt;/id&gt;
        &lt;property column="text" name="text" not-null="true" type="java.lang.String"/&gt;
        &lt;set name="answers"&gt;
            &lt;key column="question_id"/&gt;
            &lt;one-to-many class="app.Answer"/&gt;
        &lt;/set&gt;
    &lt;/class&gt;
&lt;/hibernate-mapping&gt;
</code></pre>

<p><strong>answer.hbm.xml</strong></p>

<pre><code>    &lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"&gt;
&lt;hibernate-mapping package="app"&gt;
    &lt;class name="app.Answer" table="Answer"&gt;
        &lt;id column="id" name="id" type="java.lang.Long"&gt;
            &lt;generator class="native"/&gt;
        &lt;/id&gt;
        &lt;property column="text" name="text" not-null="true" type="java.lang.String"/&gt;
        &lt;many-to-one class="app.Question" column="question_id" name="question" not-null="true"/&gt;
    &lt;/class&gt;
&lt;/hibernate-mapping&gt;
</code></pre>

<p>So in Question there is a collection of Answers. Because of this there would be a lazy load of Answers. I want to use Hibernate objects in my jsp files, so I use <a href="https://developer.jboss.org/wiki/OpenSessionInView" rel="nofollow">this technique</a>: the filter is used to create a session, and this session is used in both servlet and coresponding jsp file.</p>

<p>This is code of that my filter:</p>

<p><strong>HibernateFilter.java</strong></p>

<pre><code>package app;

import java.io.IOException;
import javax.servlet.*;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateFilter implements Filter {  

    private SessionFactory sessionFactory;  

    public void doFilter(ServletRequest request,  
                         ServletResponse response,  
                         FilterChain chain)  
            throws IOException, ServletException {    
        try {
            sessionFactory.getCurrentSession().beginTransaction();  
            chain.doFilter(request, response);  
            sessionFactory.getCurrentSession().getTransaction().commit();  
        } catch (Exception ex) { 
            sessionFactory.getCurrentSession().getTransaction().rollback();
            ex.printStackTrace();   
        }  
    }  

    public void init(FilterConfig filterConfig) throws ServletException { 
        sessionFactory = new Configuration().configure().buildSessionFactory();  
    }  

    public void destroy() {
    }    
}  
</code></pre>

<p>There are two servlets and two coresponding jsp files in my application - first ones display question with ID = 1, second ones display all questions. This is code of this servlets, coresponding jsp files and configuration of tomcat:</p>

<p><strong>GetOneQuestion.java</strong></p>

<pre><code>package app;

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import org.hibernate.Session;
import org.hibernate.cfg.Configuration;

public class GetOneQuestion extends HttpServlet { 

    @Override
    public void doGet(HttpServletRequest request, 
            HttpServletResponse response) 
            throws ServletException, IOException {  
        try {
            Session session = new Configuration().configure()
                    .buildSessionFactory().getCurrentSession();

            session.beginTransaction();
            Question question = (Question)session.load(Question.class, 1L);            
            //session.getTransaction().commit();

            request.setAttribute("oneQuestion", question); 
        } catch (Exception ex) {            
            ex.printStackTrace();
            request.setAttribute("oneQuestion", null);
        }             
        RequestDispatcher view = request.getRequestDispatcher("/oneQuestion.jsp");      
        view.forward(request, response);
    }                                                                               
}
</code></pre>

<p><strong>oneQuestion.jsp</strong></p>

<pre><code>&lt;%@page import="app.Answer"%&gt;
&lt;%@page import="app.Question"%&gt;
&lt;html&gt;
    &lt;body&gt;        
        &lt;%
            Question question = (Question)request.getAttribute("oneQuestion");            
            out.print("&lt;br&gt;" + question.getText() + "&lt;br&gt;&lt;br&gt;");             
        %&gt;           
    &lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p><strong>GetAllQuestion.java</strong></p>

<pre><code>package app;

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.List;
import org.hibernate.*;
import org.hibernate.cfg.Configuration;

public class GetAllQuestion extends HttpServlet { 

    @Override
    public void doGet(HttpServletRequest request, 
            HttpServletResponse response) 
            throws ServletException, IOException { 
        try {                 
            Session session = new Configuration().configure()
                    .buildSessionFactory().getCurrentSession();

            session.beginTransaction();        
            Query query = session.createQuery("from Question"); 
            List all = query.list();                    

            request.setAttribute("allQuestion", all);                                                        
        } catch (Exception ex) {            
            ex.printStackTrace();
            request.setAttribute("allQuestion", null);
        }             
        RequestDispatcher view = request.getRequestDispatcher("/allQuestion.jsp");      
        view.forward(request, response);
    }                                                                               
}
</code></pre>

<p><strong>allQuestion.jsp</strong></p>

<pre><code>&lt;%@page import="app.Answer"%&gt;
&lt;%@page import="app.Question"%&gt;
&lt;%@page import="java.util.List"%&gt;
&lt;html&gt;
    &lt;body&gt;       
        &lt;%
            List all = (List)request.getAttribute("allQuestion");

            for (Object object : all) {
                Question question = (Question)object;
                out.print("&lt;br&gt;Question " + question.getId());   

                for (Answer answer : question.getAnswers()) {
                    out.print("&lt;br&gt;" + answer.getText() + "&lt;br&gt;");  
                }
            }
        %&gt;           
    &lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p><strong>web.xml</strong></p>

<pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"&gt;
    &lt;filter&gt;
        &lt;filter-name&gt;HibernateFilter&lt;/filter-name&gt;
        &lt;filter-class&gt;app.HibernateFilter&lt;/filter-class&gt;
    &lt;/filter&gt;
    &lt;filter-mapping&gt;
        &lt;filter-name&gt;HibernateFilter&lt;/filter-name&gt;
        &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
    &lt;/filter-mapping&gt;
    &lt;servlet&gt;
        &lt;servlet-name&gt;getAllQuestion&lt;/servlet-name&gt;
        &lt;servlet-class&gt;app.GetAllQuestion&lt;/servlet-class&gt;
    &lt;/servlet&gt;
    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;getAllQuestion&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/getAllQuestion&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
    &lt;servlet&gt;
        &lt;servlet-name&gt;getOneQuestion&lt;/servlet-name&gt;
        &lt;servlet-class&gt;app.GetOneQuestion&lt;/servlet-class&gt;
    &lt;/servlet&gt;
    &lt;servlet-mapping&gt;
        &lt;servlet-name&gt;getOneQuestion&lt;/servlet-name&gt;
        &lt;url-pattern&gt;/getOneQuestion&lt;/url-pattern&gt;
    &lt;/servlet-mapping&gt;
    &lt;session-config&gt;
        &lt;session-timeout&gt;
            30
        &lt;/session-timeout&gt;
    &lt;/session-config&gt;
    &lt;welcome-file-list&gt;
        &lt;welcome-file&gt;index.html&lt;/welcome-file&gt;
    &lt;/welcome-file-list&gt;
&lt;/web-app&gt;
</code></pre>

<p><strong>Question</strong></p>

<p>1) Why I need to call "session.beginTransaction()" method in servlets even if I already call "session.beginTransaction()" in filter? If I call one servler from another I also have to call this method in second servlet? Or I have to call this method before every interaction with database? </p>

<p>2) I don't call "sessionFactory.getCurrentSession().openSession()" or "sessionFactory.getCurrentSession().getCurrentSession()" in filter but I call "sessionFactory.getCurrentSession().getCurrentSession()" in servlet and still obtain session which seem to be create in filter. How this can be?</p>

<p>3) If I uncomment line "session.getTransaction().commit();" in GetOneQuestion class from jsp file I receive LazyInitializationException: "could not initialize proxy - no Session" even if there is no lazy load in this jsp file because I don't use any Answer object there. What cause this Exception? Session must be open for any interaction with Hibernate object even if there is no lazy load?</p>