Announcement Announcement Module
Collapse
No announcement yet.
Inject session scoped interceptors in LocalSessionFactoryBean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Inject session scoped interceptors in LocalSessionFactoryBean

    If you have to configure the global interceptor at SessionFactory level, you do it this way

    Code:
    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
     <property name = "entityInterceptor" ref="historyInterceptor" />
    </bean>
    
    <bean id = "historyInterceptor" class="com.example.MyInterceptor" />
    MyInterceptor implements Hibernate's EmptyInterceptor. But this makes the Interceptor global interceptor. So is there a way to define an interceptor as Session scoped. I am using this procedure for my DAOs which implement HibernateDaoSupport

    Code:
    getHibernateTemplate().getSessionFactory.openSession(new MyInterceptor());
    But I hate having to do it everytime. Any suggestions would be helpful.

  • #2
    If you use OpenSessionInViewFilter then it can be extented for it:

    Code:
        <filter>
            <filter-name>Session Filter</filter-name>
            <filter-class>com.example.ExtendedOpenSessionInViewFilter</filter-class>
            <init-param>
                <param-name>singleSession</param-name>
                <param-value>true</param-value>
            </init-param>
            <init-param>
                <param-name>entityInterceptorName</param-name>
                <param-value>historyInterceptor</param-value>
            </init-param>
        </filter>
    Code:
    <bean id="historyInterceptor" class="com.example.MyInterceptor" scope="prototype" />
    Code:
    public class ExtendedOpenSessionInViewFilter extends OpenSessionInViewFilter {
    
        private String entityInterceptorName;
    
        public void setEntityInterceptorName(final String entityInterceptorName) {
            this.entityInterceptorName = entityInterceptorName;
        }
    
        @Override
        protected Session getSession(SessionFactory sessionFactory) {
            WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
            Interceptor entityInterceptor = (Interceptor) wac.getBean(entityInterceptorName, Interceptor.class);
            Session session = SessionFactoryUtils.getSession(sessionFactory, entityInterceptor, null);
            FlushMode flushMode = getFlushMode();
    
            if (flushMode != null) {
                session.setFlushMode(flushMode);
            }
    
            return session;
        }
    }

    Comment


    • #3
      I know this thread is pretty old, though I couldn't find a simple solution for it and the one I found might save other people some time. Suggested filter one creates new interceptor for each request plus it requires WebApplication context to be applied. In my situation interceptor was implemented in library used by multiple web-app that is why I didn't wanted to apply it in this level. I wanted transaction-based solution independent of web-app. I assume that you are using transaction management org.springframework.orm.hibernate3.HibernateTransa ctionManager.

      First you have to set scope of your interceptor bean to "prototype".
      Code:
      <bean id="myInterceptor"  name="myInterceptor"
      	class="com.example.MyInterceptor" scope="prototype">
      </bean>
      Than, in your transaction manager set "entityInterceptorBeanName" property to your interceptors bean name:
      Code:
      <property name="entityInterceptorBeanName" value="myInterceptor" />
      Thats it! Now you will have new interceptor for each transaction. Don't forget to remove "entityInterceptor" from LocalSessionFactoryBean. If you want to come back to singleton global interceptor or change it to request interceptor you just have to modify scope of your bean. If you want new interceptor by request you just have to change scope to "request" or other (see: http://static.springsource.org/sprin...ch04s04.html):

      Comment


      • #4
        Originally posted by wilq View Post
        I know this thread is pretty old, though I couldn't find a simple solution for it and the one I found might save other people some time. Suggested filter one creates new interceptor for each request plus it requires WebApplication context to be applied. In my situation interceptor was implemented in library used by multiple web-app that is why I didn't wanted to apply it in this level. I wanted transaction-based solution independent of web-app. I assume that you are using transaction management org.springframework.orm.hibernate3.HibernateTransa ctionManager.

        First you have to set scope of your interceptor bean to "prototype".
        Code:
        <bean id="myInterceptor"  name="myInterceptor"
        	class="com.example.MyInterceptor" scope="prototype">
        </bean>
        Than, in your transaction manager set "entityInterceptorBeanName" property to your interceptors bean name:
        Code:
        <property name="entityInterceptorBeanName" value="myInterceptor" />
        Thats it! Now you will have new interceptor for each transaction. Don't forget to remove "entityInterceptor" from LocalSessionFactoryBean. If you want to come back to singleton global interceptor or change it to request interceptor you just have to modify scope of your bean. If you want new interceptor by request you just have to change scope to "request" or other (see: http://static.springsource.org/sprin...ch04s04.html):
        Note that this only applies to Hibernate3 beans. In hibernate4 it is currently not possible to set the interceptor to the transaction manager - see https://jira.springsource.org/browse/SPR-9987 for updates on the issue.

        Comment

        Working...
        X