当前线程的问题

时间:2013-01-29 14:07:56

标签: java session spring-mvc

我是Spring的新手,当我在登录后参考下面的JSP安全性时,我遇到了“No session found the current thread”。到目前为止,一切正常。

以下是该页面的控制器:

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";
    }
}

这是从控制器调用的用户服务:

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);
    }
}

这是自定义DAO支持,不确定这是否是正确的方法....:

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();
    }
}

当然还有配置:

<?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>

成功登录后,我调用/ employee-list并获取此页面而不是页面:

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)
...

请帮我理解我的错误在哪里,也许我的配置错了?

1 个答案:

答案 0 :(得分:0)

对于那些将面临同样问题的人:我通过检查休眠设置解决了我的问题。现在他们是这样的:

<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"
   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.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
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd ">

<!-- Activates annotations -->

<context:annotation-config/>

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

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

<mvc:annotation-driven/>

<tx:annotation-driven/>

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

    <property name="annotatedClasses">
        <list>
            <value>tradeManager.model.Invoice</value>
            <value>tradeManager.model.Item</value>
            <value>tradeManager.model.User</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="/WEB-INF/database.properties"/>
</bean>

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