Announcement Announcement Module
Collapse
No announcement yet.
OpenSessionInViewFilter not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • OpenSessionInViewFilter not working

    I use Spring 1.2.6 along with Hibernate 3.0.5 on WSAD 5.1.2. I want to load an object "A" with many-to-one relationship of "B". I know Hibernate 3 comes with lazy-loading="true" by default, and it always returns me proxies instead of real objects. I tried to use the OpenSessionInViewFilter to solve the problem but failed. Following are my codes:

    web.xml
    Code:
    ...
    <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/application-context.xml</param-value>
    </context-param>
    	
    <filter>
      <filter-name>OpenSessionInViewFilter</filter-name>
      <display-name>OpenSessionInViewFilter</display-name>
      <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
      <filter-name>OpenSessionInViewFilter</filter-name>
      <url-pattern>/*</url-pattern>
    </filter-mapping>
    	
    <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    ...
    applicationContext.xml (**notice that I use "autodetect")
    Code:
    <beans default-autowire="autodetect">
    ...
    <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
      <property name="jndiName">
        <value>java:comp/env/jdbc/testDS</value>
      </property>
    </bean>
    
    <bean id="searchDao" class="test.SearchDaoHibernate"/>
    
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
      <property name="configLocation">
        <value>/WEB-INF/hibernate.cfg.xml</value>
      </property>
    </bean>
    
    <bean id="searchService" class="test.SearchServiceImpl"/>
    ...
    SearchServiceImpl.java
    Code:
    public class SearchServiceImpl implements SearchService {
    	
    	private SearchDao searchDao;
    		
    	public Data execute(String id)
    	{
    		return (Data)searchDao.search(new Integer(id));
    	}
    	
    	/**
    	 * @param dao
    	 */
    	public void setSearchDao(SearchDao dao) {
    		searchDao = dao;
    	}
    
    }
    SearchDaoHibernate.java
    Code:
    public class SearchDaoHibernate extends HibernateDaoSupport implements SearchDao{
    	
    	public Data search(Integer seqNo)
    	{
    		return (Data)getHibernateTemplate().get(test.Data.class, seqNo);
    	}
    
    }
    Data.hbm.xml
    Code:
    <hibernate-mapping>
    
        <class name="test.Data" table="m_data">
    
            <id name="id" column="m_data_seq_no">
                <generator class="native"/>
            </id>
    
            <property name="mailerName" column="mailer_name" type="string"/>
            <property name="mailerAddress" column="mailer_address" type="string"/>
            <many-to-one name="reason" column="m_reasons" class="test.Reason"/>
    
        </class>
    
    </hibernate-mapping>
    Reason.hbm.xml
    Code:
    <hibernate-mapping>
    
        <class name="test.Reason" table="reasons">
    
            <id name="id" column="m_reasons_code" type="integer">
                <generator class="native"/>
            </id>
    
            <property name="activityDate" column="activity_date" type="date"/>
            <property name="description" column="reason_description" type="string"/>
    
        </class>
    
    </hibernate-mapping>

    I could get everything to work if I only loaded Data object by using HibernateTemplate.get() (**notice that even this simple loading wouldn't work if I used HibernateTemplate.load()), but I got
    org.hibernate.LazyInitializationException could not initialize proxy - the owning Session was closed
    if I want to load Data along with Reason by using <many-to-one> relationship. I got the error on the UI tier when JSP tried to display information of Reason object. Why was this happening since I used OpenSessionInViewFilter? Shouldn't the connection not be closed and still accessible by the JSP tags (such as <bean:write> from Struts) because the response hasn't been sent yet?

    Also why didn't HibernateTemplate.load() work with this simple scenario?

    Thank you in advance.

  • #2
    I have a question, does OpenSessionInViewFilter have to be used with transaction such as HibernateTransactionManager?

    Comment


    • #3
      I noticed another thing. When I set HibernateTemplate.setAllowCreate() to false in my DAO, I got different exception.

      E SRVE0026E: [Servlet Error]-[No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here]: java.lang.IllegalStateException: No Hibernate Session bound to thread, and configuration does not allow creation of non-transactional one here
      Does this mean that my OpenSessionInViewFilter did not create a new session as it should in the first place? Can somebody please give me a hint?

      Thank you

      Comment


      • #4
        dsyliu, check out the javadoc from OpenSessionInView and the forums. The javadoc explains the use case for this class and what approaches you should take. In short, OSIV expects a session to be bind to the thread and should be allowed to create one in case it doesn't find any (the most common case). Moreover, normally you should use the transaction manager in order to persist the changes if you want to - that's a decision which belongs to the manager not to the OSIV. However you can extend OSIV to plug in your own strategy - again all this info is found inside the javadocs.

        Comment


        • #5
          Costin,

          Thank you for the reply. I checked and followed the javadoc but it still didn't work. I then created a TestFilter that extends OpenSessionInViewFilter and override the getSession() function.

          Code:
          protected Session getSession(SessionFactory sessionFactory)
          {
          	Session outSession = super.getSession(sessionFactory);
          	return outSession;
          }
          What I noticed is that the Session object (outSession) created by the filter is different from the Session object I got in my DAO (I used debugger and memory address is different). My guess is that because the HibernateTemplate in my DAO cannot find the session opened by this filter, so it creates its own and closes the session right after retrieving the result. In other words, the session created by the OpenSessionInViewFilter has never been bound and passed to the HibernateTemplate. Is this a reasonable guess? Or I totally misunderstood the process?

          Comment


          • #6
            Usually if this happens then you have more then one session factory/transaction manager. The OSIVF should bind the session to the thread - you can gain access to it easily though SessionFactoryUtils.
            Btw, what is your code suppose to do? - you just seem to return getSession without doing any logic.

            Comment

            Working...
            X