Question

OK JAVA guru ))

I really new to spring and I got into this trouble with "No session found the current thread" when I refer to the following page JSP security after login. Up to this point everything is working.

I need your help guys!!!!!

Here is my controller for that page:

package employee.controller;

import employee.service.AdminService;
import employee.service.UserService;
import org.apache.log4j.Logger;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.annotation.Resource;

/**
 * @author serge
 *
 * Handles and retrieves the common or admin page depending on the URI template.
 * A user must be log-in first he can access these pages. Only the admin can see
 * the adminpage, however.
 */
@Controller
@RequestMapping("/main")
public class MainController {

    protected static Logger logger = Logger.getLogger("controller");

    @Resource(name = "adminService")
    private AdminService adminService;

    @Resource(name = "userService")
    private UserService userService;

    /**
     * Handles and retrieves a /WEB-INF/jsp/employee-page.jsp
     *
     * containing all employee
     *
     * @return the name of the JSP page
     */

    @Secured("ROLE_USER")
    @RequestMapping(value = "/employee-list",method = RequestMethod.GET)
    public String getEmployeeListPage(Model model) {
        logger.debug("Received request to show all employee page");

        // Retrieve all employee and attach to model
        model.addAttribute("all-employee", userService.findAllEmployee());
        return "employee-page";
    }

    /**
     * Handles and retrieves /WEB-INF/jsp/admin-page.jsp that only admins can see
     *
     * @return the name of the JSP page
     */
    @Secured("ROLE_ADMIN")
    @RequestMapping(value = "/admin", method = RequestMethod.GET)
    public String getAdminPage() {
        logger.debug("Received request to show admin page");
        return "admin-page";
    }
}

This is user service that had been called from controller:

package employee.service.impl;

import employee.DAO.EmployeeInfoDAO;
import employee.model.EmployeeInfo;
import employee.service.UserService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.annotation.Secured;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author serge
 * 
 * Reader level
 * 
 * Service to Retrieve info about Employees
 */


@Service("userService")
@Transactional
public class UserServiceImpl implements UserService {
    
    protected static Logger logger = Logger.getLogger("service");
    private EmployeeInfoDAO emplInfoDAO;

    @Autowired
    public void setEmployeeDao(EmployeeInfoDAO emplInfoDAO) {
        this.emplInfoDAO = emplInfoDAO;
    }

    /**
     * Retrieving Employee Information by id
     *
     * @return EmployeeInfo object
     */
    @Override
    @Transactional
    @Secured("ROLE_USER")
    public EmployeeInfo findEmployeeByID(Integer id) {

        logger.debug("Retrieving Employee with id= " + id);
        EmployeeInfo employeeInfo = new EmployeeInfo();
        employeeInfo.setId(id);
        emplInfoDAO.find(employeeInfo);
        return employeeInfo;
    }

    /**
     * Retrieving all Employees  
     *
     * @return List of EmployeeInfo object
     */
    @Override
    @Secured("ROLE_USER")
    @Transactional(readOnly = true)
    public List<EmployeeInfo> findAllEmployee() {
        
        logger.debug("Retrieving all Employee");
        return emplInfoDAO.findAll();
    }
    
    /**
     * Retrieving Employees by last name
     *
     * @return List of EmployeeInfo object
     */
    @Override
    @Secured("ROLE_USER")
    @Transactional(readOnly = true)
    public List<EmployeeInfo> findAllByLastName(String lastName, Object paramValue) {
        lastName = "lastName";
        
        logger.debug("Retrieving Employee by last name: " + paramValue);
        return emplInfoDAO.findAllByParam(lastName, paramValue);
    }
    
    /**
     * Retrieving Employees by first name
     *
     * @return List of EmployeeInfo object
     */
    @Override
    @Secured("ROLE_USER")
    @Transactional(readOnly = true)
    public List<EmployeeInfo> findAllByFirstName(String firstName, Object paramValue) {
        firstName = "firstName";
        
        logger.debug("Retrieving Employee by first name: " + paramValue);
        return emplInfoDAO.findAllByParam(firstName, paramValue);
    }
}

And this is custom DAO support, not sure if this is right way to do that.... :

package employee.DAO.impl;

import employee.DAO.DAO;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.List;

public class CustomHibernateDaoSupport<T>  implements DAO<T> {
    //was extending HibernateDaoSupport
    
    private Class<T> clazz;
    private SessionFactory sessionFactory;

    public CustomHibernateDaoSupport(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Autowired
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }


    private Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    @Transactional
    public void save(T entity) {
        getCurrentSession().save(entity);
    }

    @Override
    @Transactional
    public void update(T entity) {
        getCurrentSession().update(entity);
    }

    @Override
    @Transactional
    public void delete(Serializable key) {
        Object entity = getCurrentSession().get(clazz, key);
        if (entity != null) {
            getCurrentSession().delete(entity);
        }
    }

    @Override
    @Transactional
    public T find(Serializable key) {
        return (T) getCurrentSession().get(clazz, key);
    }

    @Override
    @Transactional
    public List<T> findAll() {
        return getCurrentSession().createCriteria(clazz).list();
    }

    @Override
    @Transactional
    public List<T> findAllByParam(final String paramName, final Object paramValue) {
        return getCurrentSession().createCriteria(clazz)
                .add(Restrictions.eq(paramName, paramValue))
                .list();
    }
}

And of course configuration:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-3.1.xsd
            http://www.springframework.org/schema/mvc 
            http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">
    
    <!-- Activates annotations -->

    <context:annotation-config />

    <mvc:annotation-driven/>

    <!-- Scans for annotated components in base-package-->

    <context:component-scan base-package="employee" />

    <bean class="employee.service.impl.AdminServiceImpl"/>
    <bean class="employee.service.impl.UserServiceImpl"/>

    <!-- Shared Hibernate SessionFactory in a Spring application context. -->

    <bean id = "transactionManager" class = "org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name = "sessionFactory" ref = "sessionFactory" />
    </bean>

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>

        <property name="annotatedClasses">
            <list>
                <value>employee.model.UserInfo</value>
                <value>employee.model.EmployeeInfo</value>
                <value>employee.model.EmployeeDiv</value>
            </list>
        </property>

        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>
        </property>
    </bean>

    <!-- for database, imports the properties from database.properties -->

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:database.properties"/>
    </bean>
</beans>

after a successful login, I called /employee-list and got this instead of the page:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: No Session found for current thread
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
    org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:621)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
...

org.hibernate.HibernateException: No Session found for current thread
    org.springframework.orm.hibernate4.SpringSessionContext.currentSession(SpringSessionContext.java:97)
    org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:941)
    employee.DAO.impl.CustomHibernateDaoSupport.getCurrentSession(CustomHibernateDaoSupport.java:31)
    employee.DAO.impl.CustomHibernateDaoSupport.findAll(CustomHibernateDaoSupport.java:64)
...

Please help me understand where is my mistake, maybe I made a wrong configuration?

Was it helpful?

Solution

If you have dispatch-servlet.xml, add the

<tx:annotation-driven />

Or there is an alternative: Please see this: this blog

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top