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

  • OpenSessionInViewFilter PersistentSet question

    We have a Struts action that calls a service layer to return a lazily loaded Set. The service layer uses declarative transaction management and all our services look the same, aside from the class information:

    Code:
        <bean id="ordersServiceTarget" class="com.service.OrdersServiceImpl" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default"></bean>
        <bean id="ordersService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" abstract="false" singleton="true" lazy-init="default" autowire="default" dependency-check="default">
            <property name="transactionManager">
                <ref bean="transactionManager" />
            </property>
            <property name="target">
                <ref local="ordersServiceTarget" />
            </property>
            <property name="proxyTargetClass">
                <value>true</value>
            </property>
            <property name="transactionAttributes">
                <props>
                    <prop key="*">PROPAGATION_REQUIRED, ISOLATION_DEFAULT</prop>
                </props>
            </property>
        </bean>
    When we touch the Set from the action, the following error message appears:

    Code:
    failed to lazily initialize a collection of role: com.domain.Topic.questions - no session or session was closed
    With debugging turned on, the following message appears in the console output:

    Code:
    DEBUG [Finalizer] (ConnectionManager.java:369) - running Session.finalize()
    So for some reason, Spring or Hibernate determine that there is no reason to keep the session around.

    However, if the Set is touched in any way, such as a call to isEmpty(), then Session.finalize() never gets called and everything is fine at the action and view layer.

    We didn't expect the need to touch the returned collection so I'm wondering if this is expected behavior or did we stumble across a bug?

    Thanks,

    Chris

  • #2
    Your problem is quite common - objects returned from the business tier are used inside the view but since the object's relations are not initialized you have lazy exceptions. You can either initialize the relationships you need in the business tier or use the open session in view solutions (filter or interceptor) to keep the hibernate session opened during the page rendering.

    Comment


    • #3
      Costin,

      Sorry, I put OpenSessionInViewFilter in the subject title, but forgot to specify we're using it via web.xml.

      All the objects are lazily loaded - just odd that we expected to be able to just return the Set and then access it in the action and .jsp as part of the request. It just so happens that in the other service layers there's usually some interaction with the collection prior to leaving the service layer.

      Comment


      • #4
        In most cases there are some relations which are not initialized since the business tier doesn't use them. However, the view usually accesses a lot of information (for equals or smth else) - and here OSIV does become useful.

        Comment


        • #5
          Agreed. I just expected that we could return a Set that was lazily loaded and get to it from the Struts action and .jsp without problems.

          However, unless I touch the set in the service layer, nothing is accessible outside of it.

          Seeing the Session.finalize() in the console makes me think that for some reason Spring or Hibernate have decided that my lazily loaded collection should never be accessed.

          Should we be able to return a lazy Set and access it as we expect with OSIVF? If so, then there may be a bug somewhere.

          Comment


          • #6
            You have to see where the Set is used - as I said you might not access it yourself directly or intentionally.
            Session.finalize() is something hibernate specific - it just closes the session. You don't have to pay too much attention to it - it doesn't has any end user meaning.

            Comment


            • #7
              Hi cdebracy.

              What is your sessionFactory bean name?

              I faced this problem before when I had two session factories and I wanted to use OSIV for the two.

              If your sessionFactory bean name isn't called sessionFactory, specify it in OSIV filter web.xml.

              I hope it helps.

              Comment


              • #8
                fxjr,

                We're specifying the correct sessionFactory name in web.xml.

                Costin,

                The Set should be used in the .jsp, still under the auspices of OSIVF. However, we're doing some tests in the action as the .jsp is failing.

                If we touch the Set within the service layer, Session.finalize() never gets called and the Set is accessible outside the service layer but still within the OSIVF request.

                If we just return the Set, then for some reason Session.finalize() is called before leaving the service layer and any collection access within the context of that request will result in an exception.

                Comment


                • #9
                  You might have set up struts in a wrong way - several users on this forum have had this problem. A quick search should give you some nice threads with configurations and the cause for the problem.
                  I think this is your problem also - the same context is loaded twice (through Spring context listener and through Spring) and even though the configuration is correct the objects from Struts are not actually under OSIV.

                  Comment


                  • #10
                    Costin,

                    I'll take a look, but Struts knows nothing about Spring and there are no Struts-specific configuration options in our Spring application context files.

                    I will check for the possibility that the context files are loaded twice as we have a class that will try to load the context files from the web and if that fails, grab them from the classpath.

                    Chris

                    Comment

                    Working...
                    X