Java Spring@Transactional注释不工作
目前我正在做一个关于Udemy的春季课程,我对Java Spring@Transactional注释不工作,java,spring,spring-mvc,Java,Spring,Spring Mvc,目前我正在做一个关于Udemy的春季课程,我对CustomerDAO类中的@Transactional注释有问题。我正在使用Maven和Java8。它根本不起作用,下面是Tomcat 9的响应: HTTP Status 500 – Internal Server Error Type Exception Report Message Request processing failed; nested exception is javax.persistence.TransactionRequ
CustomerDAO
类中的@Transactional
注释有问题。我正在使用Maven和Java8。它根本不起作用,下面是Tomcat 9的响应:
HTTP Status 500 – Internal Server Error
Type Exception Report
Message Request processing failed; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
Description The server encountered an unexpected condition that prevented it from fulfilling the request.
Exception
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is javax.persistence.TransactionRequiredException: no transaction is in progress
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1013)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Root Cause
javax.persistence.TransactionRequiredException: no transaction is in progress
org.hibernate.internal.SessionImpl.checkTransactionNeeded(SessionImpl.java:3552)
org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1444)
org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1440)
org.springframework.orm.hibernate5.SessionFactoryUtils.flush(SessionFactoryUtils.java:147)
org.springframework.orm.hibernate5.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:95)
org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:96)
org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:922)
org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:730)
org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:714)
org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:533)
org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:304)
org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
net.matbm.springlearn.dao.CustomerDAO$$EnhancerBySpringCGLIB$$6447db19.getCustomers(<generated>)
net.matbm.springlearn.dao.CustomerDAO$HOTSWAPAGENT_$$FastClassBySpringCGLIB$$466694ed.invoke(<generated>)
org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
HotswapSpringCallback_1796692748.intercept(HotswapSpringCallback_1796692748.java)
net.matbm.springlearn.dao.CustomerDAO$HOTSWAPAGENT_$$EnhancerBySpringCGLIB$$feb7e678.getCustomers(<generated>)
net.matbm.springlearn.service.CustomerService.getAllCustomers(CustomerService.java:16)
net.matbm.springlearn.controller.CustomerController.listCustomers(CustomerController.java:26)
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:189)
org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
Note The full stack trace of the root cause is available in the server logs.
spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>spring-mvc-demo</display-name>
<!-- Spring MVC Configs -->
<!-- Step 1: Configure Spring MVC Dispatcher Servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Step 2: Set up URL mapping for Spring MVC Dispatcher Servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- Add support for component scanning -->
<context:component-scan base-package="net.matbm.springlearn.config"/>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
</beans>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.matbm</groupId>
<artifactId>SpringLearn</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Spring Learn</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>5.1.3.RELEASE</spring.version>
<jdk.version>1.8</jdk.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.7.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.3.7.Final</version>
</dependency>
</dependencies>
<build>
<finalName>SpringMaven</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>TomcatServer</server>
<path>/</path>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
net.matbm.controller.CustomerController.java
package net.matbm.springlearn.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.PooledDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import java.beans.PropertyVetoException;
import java.util.Properties;
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("net.matbm.springlearn")
public class AppConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Bean(destroyMethod = "close")
public PooledDataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource source = new ComboPooledDataSource();
source.setDriverClass("org.postgresql.Driver");
source.setJdbcUrl("jdbc:postgresql://localhost/java");
source.setUser("java");
source.setPassword("java");
source.setMinPoolSize(5);
source.setMinPoolSize(20);
source.setMinPoolSize(3000);
return source;
}
@Bean
public LocalSessionFactoryBean sessionFactory() throws PropertyVetoException {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan("net.matbm.springlearn.model");
factoryBean.setHibernateProperties(hibernateProperties());
return factoryBean;
}
@Bean
public PlatformTransactionManager transactionManager() throws PropertyVetoException {
HibernateTransactionManager manager = new HibernateTransactionManager();
manager.setSessionFactory(sessionFactory().getObject());
return manager;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("resources/");
}
private Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL95Dialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create");
return hibernateProperties;
}
}
package net.matbm.springlearn.controller;
import net.matbm.springlearn.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/customer")
public class CustomerController {
private final CustomerService customerService;
@Autowired
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
@RequestMapping()
public String home() {
return "customer/home";
}
@RequestMapping("/list")
public String listCustomers(Model model) {
model.addAttribute("customers", customerService.getAllCustomers());
return "customer/list-customers";
}
}
package net.matbm.springlearn.service;
import net.matbm.springlearn.dao.CustomerDAO;
import net.matbm.springlearn.model.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CustomerService {
@Autowired
private CustomerDAO customerDAO;
public List<Customer> getAllCustomers() {
return customerDAO.getCustomers();
}
}
package net.matbm.springlearn.dao;
import net.matbm.springlearn.model.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Repository
public class CustomerDAO {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public List<Customer> getCustomers() {
Session session = sessionFactory.getCurrentSession();
Query<Customer> query =
session.createQuery("from Customer", Customer.class);
return query.getResultList();
}
}
package net.matbm.springlearn.model;
import javax.persistence.*;
@Entity
@Table(name = "customer")
public class Customer {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
public Customer() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
'}';
}
}
net.matbm.service.CustomerService.java
package net.matbm.springlearn.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.PooledDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import java.beans.PropertyVetoException;
import java.util.Properties;
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("net.matbm.springlearn")
public class AppConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Bean(destroyMethod = "close")
public PooledDataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource source = new ComboPooledDataSource();
source.setDriverClass("org.postgresql.Driver");
source.setJdbcUrl("jdbc:postgresql://localhost/java");
source.setUser("java");
source.setPassword("java");
source.setMinPoolSize(5);
source.setMinPoolSize(20);
source.setMinPoolSize(3000);
return source;
}
@Bean
public LocalSessionFactoryBean sessionFactory() throws PropertyVetoException {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan("net.matbm.springlearn.model");
factoryBean.setHibernateProperties(hibernateProperties());
return factoryBean;
}
@Bean
public PlatformTransactionManager transactionManager() throws PropertyVetoException {
HibernateTransactionManager manager = new HibernateTransactionManager();
manager.setSessionFactory(sessionFactory().getObject());
return manager;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("resources/");
}
private Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL95Dialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create");
return hibernateProperties;
}
}
package net.matbm.springlearn.controller;
import net.matbm.springlearn.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/customer")
public class CustomerController {
private final CustomerService customerService;
@Autowired
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
@RequestMapping()
public String home() {
return "customer/home";
}
@RequestMapping("/list")
public String listCustomers(Model model) {
model.addAttribute("customers", customerService.getAllCustomers());
return "customer/list-customers";
}
}
package net.matbm.springlearn.service;
import net.matbm.springlearn.dao.CustomerDAO;
import net.matbm.springlearn.model.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CustomerService {
@Autowired
private CustomerDAO customerDAO;
public List<Customer> getAllCustomers() {
return customerDAO.getCustomers();
}
}
package net.matbm.springlearn.dao;
import net.matbm.springlearn.model.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Repository
public class CustomerDAO {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public List<Customer> getCustomers() {
Session session = sessionFactory.getCurrentSession();
Query<Customer> query =
session.createQuery("from Customer", Customer.class);
return query.getResultList();
}
}
package net.matbm.springlearn.model;
import javax.persistence.*;
@Entity
@Table(name = "customer")
public class Customer {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
public Customer() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
'}';
}
}
net.matbm.model.Customer.java
package net.matbm.springlearn.config;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.PooledDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import java.beans.PropertyVetoException;
import java.util.Properties;
@Configuration
@EnableWebMvc
@EnableTransactionManagement
@ComponentScan("net.matbm.springlearn")
public class AppConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Bean(destroyMethod = "close")
public PooledDataSource dataSource() throws PropertyVetoException {
ComboPooledDataSource source = new ComboPooledDataSource();
source.setDriverClass("org.postgresql.Driver");
source.setJdbcUrl("jdbc:postgresql://localhost/java");
source.setUser("java");
source.setPassword("java");
source.setMinPoolSize(5);
source.setMinPoolSize(20);
source.setMinPoolSize(3000);
return source;
}
@Bean
public LocalSessionFactoryBean sessionFactory() throws PropertyVetoException {
LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setPackagesToScan("net.matbm.springlearn.model");
factoryBean.setHibernateProperties(hibernateProperties());
return factoryBean;
}
@Bean
public PlatformTransactionManager transactionManager() throws PropertyVetoException {
HibernateTransactionManager manager = new HibernateTransactionManager();
manager.setSessionFactory(sessionFactory().getObject());
return manager;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("resources/");
}
private Properties hibernateProperties() {
Properties hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQL95Dialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "create");
return hibernateProperties;
}
}
package net.matbm.springlearn.controller;
import net.matbm.springlearn.service.CustomerService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/customer")
public class CustomerController {
private final CustomerService customerService;
@Autowired
public CustomerController(CustomerService customerService) {
this.customerService = customerService;
}
@RequestMapping()
public String home() {
return "customer/home";
}
@RequestMapping("/list")
public String listCustomers(Model model) {
model.addAttribute("customers", customerService.getAllCustomers());
return "customer/list-customers";
}
}
package net.matbm.springlearn.service;
import net.matbm.springlearn.dao.CustomerDAO;
import net.matbm.springlearn.model.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CustomerService {
@Autowired
private CustomerDAO customerDAO;
public List<Customer> getAllCustomers() {
return customerDAO.getCustomers();
}
}
package net.matbm.springlearn.dao;
import net.matbm.springlearn.model.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Repository
public class CustomerDAO {
@Autowired
private SessionFactory sessionFactory;
@Transactional
public List<Customer> getCustomers() {
Session session = sessionFactory.getCurrentSession();
Query<Customer> query =
session.createQuery("from Customer", Customer.class);
return query.getResultList();
}
}
package net.matbm.springlearn.model;
import javax.persistence.*;
@Entity
@Table(name = "customer")
public class Customer {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "email")
private String email;
public Customer() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
'}';
}
}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<display-name>spring-mvc-demo</display-name>
<!-- Spring MVC Configs -->
<!-- Step 1: Configure Spring MVC Dispatcher Servlet -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- Step 2: Set up URL mapping for Spring MVC Dispatcher Servlet -->
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
<?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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- Add support for component scanning -->
<context:component-scan base-package="net.matbm.springlearn.config"/>
<mvc:default-servlet-handler/>
<mvc:annotation-driven/>
</beans>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.matbm</groupId>
<artifactId>SpringLearn</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Spring Learn</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>5.1.3.RELEASE</spring.version>
<jdk.version>1.8</jdk.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.postgresql/postgresql -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.2.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator -->
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>6.0.13.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.3.7.Final</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-c3p0 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.3.7.Final</version>
</dependency>
</dependencies>
<build>
<finalName>SpringMaven</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>TomcatServer</server>
<path>/</path>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>${jdk.version}</source>
<target>${jdk.version}</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
4.0.0
net.matbm
春季学习
战争
1.0-快照
春季学习
http://maven.apache.org
5.1.3.1发布
1.8
org.springframework
弹簧芯
${spring.version}
org.springframework
弹簧网
${spring.version}
org.springframework
SpringWebMVC
${spring.version}
org.springframework
SpringJDBC
${spring.version}
org.springframework
春季甲虫
${spring.version}
javax.servlet
servlet api
3.0-α-1
假如
朱尼特
朱尼特
3.8.1
测试
org.postgresql
postgresql
42.2.5
org.hibernate.validator
休眠验证器
6.0.13.1最终版本
org.hibernate
冬眠核心
5.3.7.最终版本
org.hibernate
hibernate-c3p0
5.3.7.最终版本
斯普林马文
org.apache.tomcat.maven
tomcat7 maven插件
2.2
http://localhost:8080/manager/text
TomcatServer
/
org.apache.maven.plugins
maven编译器插件
3.8.0
${jdk.version}
${jdk.version}
提前感谢。根据例外情况,您的transactionManager配置似乎不正确 使用
平台TransactionManager
的具体原因是什么
如果没有,请使用此配置
事务usinHibernatete 4的工作配置如下所示
@Configuration
@EnableTransactionManagement
@PropertySource({ "classpath:persistence-mysql.properties" })
@ComponentScan({ "org.baeldung.spring.persistence" })
public class PersistenceConfig {
@Autowired
private Environment env;
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(restDataSource());
sessionFactory.setPackagesToScan(
new String[] { "org.baeldung.spring.persistence.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
@Bean
public DataSource restDataSource() {
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
@Autowired
public HibernateTransactionManager transactionManager(
SessionFactory sessionFactory) {
HibernateTransactionManager txManager
= new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
Properties hibernateProperties() {
return new Properties() {
{
setProperty("hibernate.hbm2ddl.auto",
env.getProperty("hibernate.hbm2ddl.auto"));
setProperty("hibernate.dialect",
env.getProperty("hibernate.dialect"));
setProperty("hibernate.globally_quoted_identifiers",
"true");
}
};
}
}
更多细节
Else如果您想要PlatformTransactionManager的解决方案
更改
客户DAO
后,可能会有帮助,事务开始工作:
@Repository
public class CustomerDAOImpl implements CustomerDAO {
@PersistenceContext
private EntityManager entityManager;
public List<Customer> getCustomers() {
Query<Customer> query =
(Query<Customer>) entityManager.createQuery("from Customer", Customer.class);
return query.getResultList();
}
}
@存储库
公共类CustomerDAOImpl实现CustomerDAO{
@持久上下文
私人实体管理者实体管理者;
公共列表getCustomers(){
查询=
(Query)entityManager.createQuery(“来自客户”,Customer.class);
返回query.getResultList();
}
}
使用
@PersistenceContext
而不是会话工厂
解决了问题。我不知道为什么。在服务层,您使用了@Autowired注释,在DAO层,您使用了@Tranjaction注释,因此它给出了一个错误
因此,在服务层中使用@Transactional注释,在DAO层中使用@Autowired注释
在如下所示的服务层中进行更改
import net.matbm.springlearn.dao.CustomerDAO;
import net.matbm.springlearn.model.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CustomerService {
@Autowired
private CustomerDAO customerDAO;
@Transactional
public List<Customer> getAllCustomers() {
return customerDAO.getCustomers();
}
}
package net.matbm.springlearn.dao;
import net.matbm.springlearn.model.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Repository
public class CustomerDAO {
@Autowired
private SessionFactory sessionFactory;
@Override
public List<Customer> getCustomers() {
Session session = sessionFactory.getCurrentSession();
Query<Customer> query =
session.createQuery("from Customer", Customer.class);
return query.getResultList();
}
}
import net.matbm.springlearn.dao.CustomerDAO;
导入net.matbm.springlearn.model.Customer;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.stereotype.Service;
导入java.util.List;
@服务
公共类客户服务{
@自动连线
私人客户道客户道;
@交易的
公共列表getAllCustomers(){
返回customerDAO.getCustomers();
}
}
在DAO层中进行更改,如下所示
import net.matbm.springlearn.dao.CustomerDAO;
import net.matbm.springlearn.model.Customer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CustomerService {
@Autowired
private CustomerDAO customerDAO;
@Transactional
public List<Customer> getAllCustomers() {
return customerDAO.getCustomers();
}
}
package net.matbm.springlearn.dao;
import net.matbm.springlearn.model.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.query.Query;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Repository
public class CustomerDAO {
@Autowired
private SessionFactory sessionFactory;
@Override
public List<Customer> getCustomers() {
Session session = sessionFactory.getCurrentSession();
Query<Customer> query =
session.createQuery("from Customer", Customer.class);
return query.getResultList();
}
}
package net.matbm.springlearn.dao;
导入net.matbm.springlearn.model.Customer;
导入org.hibernate.Session;
导入org.hibernate.SessionFactory;
导入org.hibernate.query.query;
导入org.springframework.beans.factory.annotation.Autowired;
导入org.springframework.stereotype.Repository;
导入org.springframework.transaction.annotation.Transactional;
导入java.util.List;
@存储库
公共类客户道{
@自动连线
私人会话工厂会话工厂;
@凌驾
公共列表getCustomers(){
Session Session=sessionFactory.getCurrentSession();
查询=
createQuery(“来自客户”,Customer.class);
返回query.getResultList();
}
}
我不知道您的问题,只需在服务层使用@Transactional
。我也尝试过(我查看了文档,应该在服务层使用)。但这并没有解决问题。嗨,谢谢你的快速回复。我曾经设置过平台TransactionManager
,这就是我使用它的原因。不幸的是,做出您建议的更改并没有解决问题。在创建此问题之前,我已经查看了您发布的第二个链接。我在这里发表了评论:这也是问题所在,官方文档指定@Transactional
需要位于服务层。