Spring Hibernate 5异常:HibernateException:无法获取当前线程的事务同步Session

时间:2018-05-20 00:52:42

标签: java spring hibernate spring-mvc

我在Github上用Baeldung进行训练,但现在得到了例外

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:986)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:881)
javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

root cause
org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
org.springframework.orm.hibernate5.SpringSessionContext.currentSession(SpringSessionContext.java:136)
org.hibernate.internal.SessionFactoryImpl.getCurrentSession(SessionFactoryImpl.java:465)
common.dao.AbstractHibernateDAO.getCurrentSession(AbstractHibernateDAO.java:54)
common.dao.AbstractHibernateDAO.create(AbstractHibernateDAO.java:31)
com.department.model.DepartmentServiceImpl.addDepartment(DepartmentServiceImpl.java:21)
com.controller.DepartmentController.Insert(DepartmentController.java:29)
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
java.lang.reflect.Method.invoke(Method.java:498)
org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:871)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:777)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:881)
javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

我谷歌关于这个例外并了解它的注释,例如@Service @Controller @Repository @Transactional并添加

我也使用Junit,它工作正常

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

   @Override
   protected Class<?>[] getRootConfigClasses() {
      return new Class[] { HibernateConf.class };
   }

   @Override
   protected Class<?>[] getServletConfigClasses() {
      return new Class[] { WebMvcConfig.class };
   }

   @Override
   protected String[] getServletMappings() {
      return new String[] { "/" };
   }
}

hibernate config

import java.util.Properties;

import javax.sql.DataSource;

import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.department.model.DepartmentDAOImpl;
import com.department.model.DepartmentVO;
import com.employee.model.EmployeeDAOImpl;
import com.employee.model.EmployeeVO;
import com.project.model.ProjectDAOImpl;
import com.project.model.ProjectVO;

@Configuration
@EnableTransactionManagement
@PropertySource({"classpath:persistence-h2.properties"})
@ComponentScan({"com.controller","com.department.model" , "com.employee.model" , "com.project.model"})
public class HibernateConf {

@Autowired
private Environment env;

@Bean
public LocalSessionFactoryBean sessionFactory() {
    final LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
    sessionFactory.setDataSource(dataSource());
    sessionFactory.setAnnotatedClasses(DepartmentVO.class , EmployeeVO.class , ProjectVO.class);
    sessionFactory.setHibernateProperties(hibernateProperties());
    return sessionFactory;
}

@Bean
public DataSource dataSource() {
    final BasicDataSource dataSource = new BasicDataSource();
    dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
    dataSource.setUrl(env.getProperty("jdbc.url"));
    dataSource.setUsername(env.getProperty("jdbc.user"));
    dataSource.setPassword(env.getProperty("jdbc.pass"));       
    return dataSource;
}

@Bean
public PlatformTransactionManager hibernateTransactionManager() {
    HibernateTransactionManager transactionManager = new HibernateTransactionManager();
    transactionManager.setSessionFactory(sessionFactory().getObject());
    return transactionManager;
}

@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
    return new PersistenceExceptionTranslationPostProcessor();
}   

@Bean
public DepartmentDAOImpl departmentDAOImpl() {
    return new DepartmentDAOImpl();
}

@Bean
public EmployeeDAOImpl employeeDAOImpl() {
    return new EmployeeDAOImpl();
}

@Bean
public ProjectDAOImpl projectDAOImpl() {
    return new ProjectDAOImpl();
}

private final Properties hibernateProperties() {
    final Properties hibernateProps = new Properties();
    hibernateProps.setProperty("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto"));
    hibernateProps.setProperty("hibernate.dialect", env.getProperty("hibernate.dialect"));
    hibernateProps.setProperty("hibernate.show_sql", env.getProperty("hibernate.show_sql"));
    hibernateProps.setProperty("hibernate.format_sql", env.getProperty("hibernate.format_sql"));
    hibernateProps.setProperty("hibernate.id.new_generator_mappings","false");
    return hibernateProps;
}   
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.eventGeneratedId=
jdbc.user=root
jdbc.pass=3524
hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
hibernate.show_sql=true
hibernate.format_sql=true
hibernate.hbm2ddl.auto=update
hibernate.search.default.directory_provider = filesystem
hibernate.search.default.indexBase = /data/index/default
envers.audit_table_suffix=_audit_log

webmvcconfig

@Configuration
@EnableWebMvc
@ComponentScan({"com.controller","com.department.model" , "com.employee.model" , "com.project.model"})
public class WebMvcConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver resolver() {
  InternalResourceViewResolver resolver = new InternalResourceViewResolver();
  resolver.setViewClass(JstlView.class);
  resolver.setPrefix("/WEB-INF/");
  resolver.setSuffix(".jsp");
  return resolver;
}

}

实体

package com.department.model;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import com.employee.model.EmployeeVO;

@Entity
@Table(name = "department")
public class DepartmentVO implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "department_id")
private Integer department_id;

@Column(name = "dname")
private String dname;

@Column(name = "loc")
private String loc;

@OneToMany(cascade = CascadeType.ALL , mappedBy = "departmentVO" , fetch = FetchType.EAGER) // lazy = false
private Set<EmployeeVO> employees = new HashSet<EmployeeVO>();

public DepartmentVO() {
    super();
}

public Integer getDepartment_id() {
    return department_id;
}

public void setDepartment_id(Integer department_id) {
    this.department_id = department_id;
}

public String getDname() {
    return dname;
}

public void setDname(String dname) {
    this.dname = dname;
}

public String getLoc() {
    return loc;
}

public void setLoc(String loc) {
    this.loc = loc;
}

public Set<EmployeeVO> getEmployees() {
    return employees;
}

public void setEmployees(Set<EmployeeVO> employees) {
    this.employees = employees;
}

}

和普通dao请访问common dao它是相同的

package com.department.model;

import java.util.Set;

import common.dao.Operations;

public interface DepartmentDAO extends Operations<DepartmentVO> {

}

package com.department.model;

import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import common.dao.AbstractHibernateDAO;

@Repository
@Transactional
public class DepartmentDAOImpl extends AbstractHibernateDAO<DepartmentVO> implements DepartmentDAO {

public DepartmentDAOImpl() {
    super();

    setClazz(DepartmentVO.class);
}
}

服务

package com.department.model;

import java.util.List;

public interface DepartmentService {

List<DepartmentVO> getAll();
void addDepartment(DepartmentVO departmentVO);
}

package com.department.model;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DepartmentServiceImpl implements DepartmentService{

@Autowired
private DepartmentDAO dao;

@Override
public List<DepartmentVO> getAll() {
    return dao.findAll();
}

@Override
public void addDepartment(DepartmentVO departmentVO) {
    dao.create(departmentVO);
}
}

控制器

package com.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.department.model.DepartmentService;
import com.department.model.DepartmentVO;

@Controller
@RequestMapping("/dept")
public class DepartmentController {

@Autowired
private DepartmentService deptSvc;

@GetMapping("addDept")
public String addDept(ModelMap model) {
    DepartmentVO departmentVO = new DepartmentVO();
    model.addAttribute("departmentVO" , departmentVO);
    return "dept/addDept";
}

@PostMapping("insert")
public String Insert(DepartmentVO departmentVO , ModelMap model) {
    deptSvc.addDepartment(departmentVO);
    return "dept/addDept";
}
}

1 个答案:

答案 0 :(得分:0)

我很确定我使用了与您相同的教程,并且我在服务类而不是存储库上有@Transactional注释。我不明白为什么会有所作为,但你尝试过这种方式吗?我遇到了完全相同的错误,这是因为我的主线程崩溃是因为缺少bean而实体管理器正在关闭导致其他线程无法启动事务。