2

I'm trying to create a REST service using spring and JackSon JSON.

My DAOImpl:

    @Override
    @SuppressWarnings("unchecked")
    public Users findByUserName(String username) {

        Users user = new Users();
        session = getSessionFactory().openSession();
        try {
            transaction = session.beginTransaction();
            if (!username.isEmpty() && username != null) {
                List<Users> users = new ArrayList<Users>();
                users = session.createQuery("from Users where username=?")
                        .setParameter(0, username)
                        .list();

                if (!users.isEmpty()) {
                    user = users.get(0);
                }

                transaction.commit();
            }
        } catch (HibernateException e) {

            if (transaction != null) {
                transaction.rollback();
            }

            e.printStackTrace();
        } finally {
            session.close();
        }

        return user;
    }

My Controller class:

    @RequestMapping(value = "/rest/userbyname/{username}",
            method = RequestMethod.GET,
            headers = "Accept=application/json")
    public Users findByUserName(@PathVariable("username") String username) {

        return userDao.findByUserName(username);
    }

And I'm getting this error:

HTTP Status 500 - Could not write JSON: could not initialize proxy - no Session (through reference chain: com.spring.example.entities.Users["roles"]->com.enclaveit.brea.entities.Roles_$$_jvstd4_2["role"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: com.enclaveit.brea.entities.Users["roles"]->com.enclaveit.brea.entities.Roles_$$_jvstd4_2["role"])

As I understand because the session is closed in DAOImpl class so in the controller the session is no more, is it correct? When I try to comment the code line session.close(); then the web work fine, I can receive the Json. But it is dangerous when a session couldn't close, right?

Looking for best solution.

NOTE: If you need more information please tell me.

Thank you.

UPDATE:

Hibernate config file:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- MySQL data source -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://192.168.10.116:3306/brea" />
        <property name="username" value="root" />
        <property name="password" value="brea@123" />
        <property name="maxActive" value="-1"/>
    </bean>
    <!-- If request parameter "targetUrl" is existed, then forward to this url --> 
    <!-- For update login form -->
    <bean id="savedRequestAwareAuthenticationSuccessHandler"
        class="org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler">
        <property name="targetUrlParameter" value="targetUrl" />
     </bean>
    <!-- Hibernate session factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mappingResources">
            <list>
                <value>orm/Roles.hbm.xml</value>
                <value>orm/Users.hbm.xml</value>
                <value>orm/UsersInfo.hbm.xml</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
            <prop key="hibernate.dialect">
                           org.hibernate.dialect.MySQL5Dialect
                        </prop>
            <prop key="hibernate.format_sql">true</prop>
            <prop key="hibernate.show_sql">true</prop>
            </props>
        </property>
    </bean>

    <bean id="userDao" class="com.enclaveit.brea.dao.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <bean id="myUserDetailsService" 
                class="com.enclaveit.brea.services.MyUserDetailsService">
        <property name="userDao" ref="userDao" />
    </bean>

    <tx:annotation-driven />

    <!-- MUST have transaction manager, using aop and aspects  -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="dataSource" ref="dataSource" />
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
        <tx:method name="get*" read-only="true" />
        <tx:method name="find*" read-only="true" />
        <tx:method name="*" />
        </tx:attributes>
    </tx:advice>

    <aop:config>
        <aop:pointcut id="userServicePointCut"
        expression="execution(* com.enclaveit.brea.services.*Service.*(..))" />
        <aop:advisor advice-ref="txAdvice" pointcut-ref="userServicePointCut" />
    </aop:config>
</beans>

Error log:

com.fasterxml.jackson.databind.JsonMappingException: could not initialize proxy - no Session (through reference chain: com.spring.example.entities.Users["roles"]->com.spring.example.entities.Roles_$$_jvstdf1_2["role"])
    com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:232)
    com.fasterxml.jackson.databind.JsonMappingException.wrapWithPath(JsonMappingException.java:197)
    com.fasterxml.jackson.databind.ser.std.StdSerializer.wrapAndThrow(StdSerializer.java:184)
    com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:605)
    com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:142)
    com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:569)
    com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:597)
    com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:142)
    com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:118)
    com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:1819)
    org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal(MappingJackson2HttpMessageConverter.java:241)
    org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:207)
    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:148)
    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90)
    org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:193)
    org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:139)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)

org.hibernate.LazyInitializationException: could not initialize proxy - no Session
    org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:164)
    org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:285)
    org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185)
    com.spring.example.entities.Roles_$$_jvstdf1_2.getRole(Roles_$$_jvstdf1_2.java)
    sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    java.lang.reflect.Method.invoke(Method.java:606)
    com.fasterxml.jackson.databind.ser.BeanPropertyWriter.get(BeanPropertyWriter.java:679)
    com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:534)
    com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:597)
    com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:142)
    com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:569)
    com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:597)
    com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:142)
    com.fasterxml.jackson.databind.ser.DefaultSerializerProvider.serializeValue(DefaultSerializerProvider.java:118)
    com.fasterxml.jackson.databind.ObjectMapper.writeValue(ObjectMapper.java:1819)
    org.springframework.http.converter.json.MappingJackson2HttpMessageConverter.writeInternal(MappingJackson2HttpMessageConverter.java:241)
    org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:207)
    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:148)
    org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodProcessor.writeWithMessageConverters(AbstractMessageConverterMethodProcessor.java:90)
    org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.handleReturnValue(RequestResponseBodyMethodProcessor.java:193)
    org.springframework.web.method.support.HandlerMethodReturnValueHandlerComposite.handleReturnValue(HandlerMethodReturnValueHandlerComposite.java:71)
    org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:122)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749)
    org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:690)
    org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:945)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:139)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:108)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
    org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
    org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
3
  • 1
    Use @Transactional and let spring handle the transaction Commented Sep 16, 2015 at 8:26
  • Add the complete stacktrace please Commented Sep 16, 2015 at 8:27
  • Don't handle transactions and sessions yourself. Use Spring to do it for you. Next either return everything you need to create the JSON response or use a OpenSessionInViewFilter to keep the session open until the request finishes processing. Commented Sep 16, 2015 at 8:30

3 Answers 3

4

Adding the proxy annotation to the Entity class does the job.

@Entity @Table(name="Country") @Proxy(lazy = false) public class Country {}
Sign up to request clarification or add additional context in comments.

Comments

0

The quickest solution is to first remove the session and transaction handling code from your service and simply replace it with @Transactional in your code (and <tx:annotation-driven /> in your configuration.

@Override
@SuppressWarnings("unchecked")
@Transactional(readOnly="true")
public Users findByUserName(String username) {
    Session session = getSessionFactory().getCurrentSession();      
    return (Users) session
                    .createQuery("from Users where username=?")
                    .setParameter(0, username)
                    .uniqueResult();
}

Also note that session should be scoped to the method NEVER store the Session as in instance variable. (Imagine what would happen if 10 current calls to findByUserName are made what would happen to the instance variable session).

In your configuration enable annotation driven transaction management. (Assuming you already have a HibernateTransactionManager definedn!).

<tx:annotation-driven />

Next add an OpenSessionInViewFilter to your request handling chain (i.e. register the filter in your web.xml or initializer when using java config).

<filter>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
    <!-- Replace with hibernate3, hibernate4 or hibernate5 depending on the hibernate version one uses -->
</filter>

<filter-mapping>
    <filter-name>OpenSessionInViewFilter</filter-name>
    <servlet-name>dispatcher</servlet-name> <!-- name of your DispatcherServlet -->
</filter-mapping>

1 Comment

Then you haven't configured the OpenSessionInViewFilter correctly OR haven't implemented the method correctly. Note the getCurrentSession and not openSession!. Or your hibernate configuration is wrong and not properly integrated with Springs Tx management. Add the hibernate configuration to your question.
0

Since you are working with Spring framework, make use of declarative transaction management instead of programmatic transactions.

I believe your Users entity has role property with lazy loading. Either you can change this to eager loading (not preferable) or in DAO method load the role information using getter user.getRole() before session close.

2 Comments

Is there any other choice to keep lazy loading?
Yes in DAO method load the role information using getter (something like user.getRole()) before session close.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.