Spring 无法识别@Transactional 注释
Spring doesn't recognize @Transactional annotations
我需要一些帮助。
Spring 似乎无法识别我用@Transactional 注释的方法。我看了很多解决方案的来源,但找不到。
而且我需要准确注释 dao 方法,而不是服务(我知道这是最佳实践)。
P.S。抱歉我的英语不好。
我的 appInitializer:
package com.dreamteam.datavisualizator.common.configurations;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{ServletContext.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{ApplicationContext.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
我的 servletContext:
package com.dreamteam.datavisualizator.common.configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
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.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@ComponentScan(basePackages = "com.dreamteam.datavisualizator")
@EnableWebMvc
@EnableTransactionManagement
public class ServletContext extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
我的应用程序上下文:
package com.dreamteam.datavisualizator.common.configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@Configuration
public class ApplicationContext {
@Bean(name = "dataSource")
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl(System.getenv("SQL_JDBC_URL"));
dataSource.setUsername(System.getenv("SQL_LOGIN"));
dataSource.setPassword(System.getenv("SQL_PASSWORD"));
return dataSource;
}
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(getDataSource());
}
@Bean(name="generalTemplate")
public JdbcTemplate getJdbcTemplate(){
return new JdbcTemplate(getDataSource());
}
@Bean(name="simpleCallTemplate")
public SimpleJdbcCall getSimpleJdbcCall(){
return new SimpleJdbcCall(getDataSource());
}
}
My Dao class(在此方法中可以多次调用 SimpleJdbcCall/ 但例如):
@Repository("userDaoImpl")
public class UserDAOImpl implements UserDAO {
private enum UserColumnName {ID, FIRST_NAME, LAST_NAME, EMAIL}
@Autowired
private JdbcTemplate generalTemplate;
@Autowired
private SimpleJdbcCall simpleCallTemplate;
//...
@Transactional
public BigInteger createObject(BigInteger object_id, String name) {
simpleCallTemplate.withFunctionName(INSERT_OBJECT);
SqlParameterSource in = new MapSqlParameterSource()
.addValue("obj_type_id", object_id)
.addValue("obj_name", name);
return simpleCallTemplate.executeFunction(BigDecimal.class, in).toBigInteger();
}
//...
private String INSERT_OBJECT = "insert_object";
}
可能是因为Open Session?
https://vladmihalcea.com/the-open-session-in-view-anti-pattern/
在属性文件中试试:
spring.jpa.open-在视图中=false
您的配置似乎是正确的。我相信它不起作用,因为您没有指定 rollbackFor
@Transactional(value = "transactionManager", rollbackFor = java.lang.Exception.class)
public BigInteger createObject(BigInteger object_id, String name) {
simpleCallTemplate.withFunctionName(INSERT_OBJECT);
SqlParameterSource in = new MapSqlParameterSource()
.addValue("obj_type_id", object_id)
.addValue("obj_name", name);
return simpleCallTemplate.executeFunction(BigDecimal.class, in).toBigInteger();
}
现在,如果您的方法中出现 java.lang.Exception 类型的异常,它将回滚所有更改
我需要一些帮助。 Spring 似乎无法识别我用@Transactional 注释的方法。我看了很多解决方案的来源,但找不到。 而且我需要准确注释 dao 方法,而不是服务(我知道这是最佳实践)。 P.S。抱歉我的英语不好。
我的 appInitializer:
package com.dreamteam.datavisualizator.common.configurations;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
protected Class<?>[] getRootConfigClasses() {
return new Class[]{ServletContext.class};
}
protected Class<?>[] getServletConfigClasses() {
return new Class[]{ApplicationContext.class};
}
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
我的 servletContext:
package com.dreamteam.datavisualizator.common.configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
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.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@ComponentScan(basePackages = "com.dreamteam.datavisualizator")
@EnableWebMvc
@EnableTransactionManagement
public class ServletContext extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
}
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
我的应用程序上下文:
package com.dreamteam.datavisualizator.common.configurations;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@Configuration
public class ApplicationContext {
@Bean(name = "dataSource")
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("oracle.jdbc.driver.OracleDriver");
dataSource.setUrl(System.getenv("SQL_JDBC_URL"));
dataSource.setUsername(System.getenv("SQL_LOGIN"));
dataSource.setPassword(System.getenv("SQL_PASSWORD"));
return dataSource;
}
@Bean(name = "transactionManager")
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(getDataSource());
}
@Bean(name="generalTemplate")
public JdbcTemplate getJdbcTemplate(){
return new JdbcTemplate(getDataSource());
}
@Bean(name="simpleCallTemplate")
public SimpleJdbcCall getSimpleJdbcCall(){
return new SimpleJdbcCall(getDataSource());
}
}
My Dao class(在此方法中可以多次调用 SimpleJdbcCall/ 但例如):
@Repository("userDaoImpl")
public class UserDAOImpl implements UserDAO {
private enum UserColumnName {ID, FIRST_NAME, LAST_NAME, EMAIL}
@Autowired
private JdbcTemplate generalTemplate;
@Autowired
private SimpleJdbcCall simpleCallTemplate;
//...
@Transactional
public BigInteger createObject(BigInteger object_id, String name) {
simpleCallTemplate.withFunctionName(INSERT_OBJECT);
SqlParameterSource in = new MapSqlParameterSource()
.addValue("obj_type_id", object_id)
.addValue("obj_name", name);
return simpleCallTemplate.executeFunction(BigDecimal.class, in).toBigInteger();
}
//...
private String INSERT_OBJECT = "insert_object";
}
可能是因为Open Session? https://vladmihalcea.com/the-open-session-in-view-anti-pattern/
在属性文件中试试: spring.jpa.open-在视图中=false
您的配置似乎是正确的。我相信它不起作用,因为您没有指定 rollbackFor
@Transactional(value = "transactionManager", rollbackFor = java.lang.Exception.class)
public BigInteger createObject(BigInteger object_id, String name) {
simpleCallTemplate.withFunctionName(INSERT_OBJECT);
SqlParameterSource in = new MapSqlParameterSource()
.addValue("obj_type_id", object_id)
.addValue("obj_name", name);
return simpleCallTemplate.executeFunction(BigDecimal.class, in).toBigInteger();
}
现在,如果您的方法中出现 java.lang.Exception 类型的异常,它将回滚所有更改