我有一个项目 https://github.com/ivartanian/onlinecontrol 在Spring MVC + JPA中,最初通过XML使用Spring配置。现在我试图通过JAVA Config(没有XML)设置项目。项目启动,但是当我创建新用户(实体用户)时,出现错误事务。但是,如果我创建另一个实体,则不会发生此错误。如果不发生此XML配置错误。
请告诉我错误的原因。 我很乐意提供任何帮助
我的XML配置是:
<context:component-scan
base-package="com.vizaco.onlinecontrol.service"/>
<!-- enables scanning for @Transactional annotations -->
<tx:annotation-driven/>
<!-- ========================= DATASOURCE DEFINITION ========================= -->
<!-- Configurer that replaces ${...} placeholders with values from a properties file -->
<!-- (in this case, JDBC-related settings for the dataSource definition below) -->
<context:property-placeholder location="classpath:spring/data-access.properties" system-properties-mode="OVERRIDE"/>
<!-- Database initializer. If any of the script fails, the initialization stops. -->
<!-- As an alternative, for embedded databases see <jdbc:embedded-database/>. -->
<jdbc:initialize-database data-source="dataSource">
<jdbc:script location="${jdbc.initLocation}"/>
<jdbc:script location="${jdbc.dataLocation}"/>
</jdbc:initialize-database>
<!-- DataSource configuration for the Jetty jdbc connection -->
<bean id="dataSource" class="org.hsqldb.jdbc.JDBCDataSource">
<property name="url">
<value>${jdbc.url}</value>
</property>
<property name="user">
<value>${jdbc.username}</value>
</property>
<property name="password">
<value>${jdbc.password}</value>
</property>
</bean>
<context:component-scan base-package="com.vizaco.onlinecontrol.dao.jpa"/>
<context:component-scan base-package="com.vizaco.onlinecontrol.security"/>
<context:component-scan base-package="com.vizaco.onlinecontrol.configuration"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:dataSource-ref="dataSource">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="${jpa.database}" p:showSql="${jpa.showSql}"/>
<!-- the 'database' parameter refers to the database dialect being used.
By default, Hibernate will use a 'HSQL' dialect because 'jpa.database' has been set to 'HSQL'
inside file spring/data-access.properties
-->
</property>
</bean>
<!-- Transaction manager for a single JPA EntityManagerFactory (alternative to JTA) -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory"/>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- Voters -->
<bean id="accessDecisionManager"
class="org.springframework.security.access.vote.AffirmativeBased">
<constructor-arg name="decisionVoters">
<list>
<bean class="org.springframework.security.access.vote.RoleVoter"/>
</list>
</constructor-arg>
</bean>
<!--<bean id="expressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">-->
<!--<property name="permissionEvaluator" ref="customPermissionEvaluator"/>-->
<!--</bean>-->
<!--<bean id="customPermissionEvaluator" class="com.vizaco.onlinecontrol.security.impl.CustomPermissionEvaluator"/>-->
<!-- SECURITY -->
<bean id="passwordEncoder" class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">
<constructor-arg name="strength" value="11"/>
</bean>
<!-- Validators -->
<bean id="userValidator" class="com.vizaco.onlinecontrol.validators.UserValidator"/>
<!-- Messages -->
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basename" value="classpath:messages"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
<property name="defaultLocale" value="ru"/>
</bean>
<!-- Converters -->
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.vizaco.onlinecontrol.converters.StringToClazz"/>
<bean class="com.vizaco.onlinecontrol.converters.StringToUser"/>
</set>
</property>
</bean>
</beans>
我的Java配置是:
@Configuration
@EnableWebMvc
@EnableAspectJAutoProxy
@EnableTransactionManagement
@ComponentScan({
"com.vizaco.onlinecontrol.aspects",
"com.vizaco.onlinecontrol.configuration",
"com.vizaco.onlinecontrol.controller",
"com.vizaco.onlinecontrol.dao",
"com.vizaco.onlinecontrol.model",
"com.vizaco.onlinecontrol.validators",
"com.vizaco.onlinecontrol.security",
"com.vizaco.onlinecontrol.service"})
@PropertySource("classpath:spring/data-access.properties")
public class WebConfig extends WebMvcConfigurerAdapter implements TransactionManagementConfigurer {
@Autowired
Environment environment;
@Autowired
private ClazzService clazzService;
@Autowired
private UserService userService;
@Autowired
private MethodSecurityMetadataSourceAdvisor sourceAdvisor;
@Bean
public UserDetailsService userDetailsService() {
return new CustomUserDetailsServiceImpl();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public DataSource dataSource() {
JDBCDataSource dataSource = new JDBCDataSource();
dataSource.setUrl(environment.getProperty("jdbc.url"));
dataSource.setUser(environment.getProperty("jdbc.username"));
dataSource.setPassword(environment.getProperty("jdbc.password"));
return dataSource;
}
@Bean
public DataSourceInitializer dataSourceInitializer() {
DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
dataSourceInitializer.setDataSource(dataSource());
CompositeDatabasePopulator compositeDatabasePopulator = new CompositeDatabasePopulator();
compositeDatabasePopulator.addPopulators(new ResourceDatabasePopulator(new DefaultResourceLoader().getResource(environment.getProperty("jdbc.initLocation"))));
compositeDatabasePopulator.addPopulators(new ResourceDatabasePopulator(new DefaultResourceLoader().getResource(environment.getProperty("jdbc.dataLocation"))));
dataSourceInitializer.setDatabasePopulator(compositeDatabasePopulator);
return dataSourceInitializer;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(dataSource());
em.setPackagesToScan(new String[]{"com.vizaco.onlinecontrol.model"});
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
vendorAdapter.setDatabase(Database.HSQL);
vendorAdapter.setShowSql(true);
em.setJpaVendorAdapter(vendorAdapter);
Properties properties = new Properties();
properties.setProperty("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
em.setJpaProperties(properties);
return em;
}
@Bean
public PlatformTransactionManager txManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return txManager();
}
@Bean
public PersistenceExceptionTranslationPostProcessor exceptionTranslation() {
return new PersistenceExceptionTranslationPostProcessor();
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/WEB-INF/jsp/**").addResourceLocations("/jsp/");
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true)
.useJaf(false)
.ignoreAcceptHeader(true)
.mediaType("html", MediaType.TEXT_HTML)
.mediaType("json", MediaType.APPLICATION_JSON)
.defaultContentType(MediaType.TEXT_HTML);
}
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/jsp/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
registry.viewResolver(resolver);
registry.beanName();
}
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new StringToClazz(clazzService));
registry.addConverter(new StringToUser(userService));
}
@Bean(name = "messageSource")
public MessageSource configureMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:messages");
messageSource.setCacheSeconds(5);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
@Bean
public CookieLocaleResolver localeResolver() {
CookieLocaleResolver localeResolver = new CookieLocaleResolver();
localeResolver.setDefaultLocale(new Locale("ru"));
return localeResolver;
}
}
在方法save(用户用户)中调用this.em.persist(user)时发生错误:
@Repository
public class JpaUserDaoImpl implements UserDao {
@PersistenceContext
private EntityManager em;
public JpaUserDaoImpl() {
}
public JpaUserDaoImpl(EntityManager em) {
this.em = em;
}
@Override
public User findByEmail(String email) throws DataAccessException {
Query query = this.em.createQuery("SELECT DISTINCT user FROM User user WHERE user.email =:email");
query.setParameter("email", email);
List resultList = query.getResultList();
if (resultList.isEmpty()) {
return null; // handle no-results case
} else {
return (User)resultList.get(0);
}
// return (User) query.getSingleResult();
}
@Override
public User findById(Long id) {
Query query = this.em.createQuery("SELECT DISTINCT user FROM User user WHERE user.id =:id");
query.setParameter("id", id);
List resultList = query.getResultList();
if (resultList.isEmpty()) {
return null; // handle no-results case
} else {
return (User)resultList.get(0);
}
}
@Override
public List<User> getAllUsers() throws DataAccessException {
Query query = this.em.createQuery("SELECT DISTINCT user FROM User user");
return query.getResultList();
}
@Override
public void save(User user) {
if (user == null){
return;
}
if (user.getId() == null) {
this.em.persist(user);
}
else {
this.em.merge(user);
}
}
@Override
public void delete(User user) throws DataAccessException {
if (user == null){
return;
}
this.em.remove(user);
}
}
那个错误:
javax.persistence.TransactionRequiredException: No transactional EntityManager available
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:275)
at com.sun.proxy.$Proxy64.persist(Unknown Source)
at com.vizaco.onlinecontrol.dao.jpa.JpaUserDaoImpl.save(JpaUserDaoImpl.java:68)
at com.vizaco.onlinecontrol.service.impl.UserServiceImpl.saveUser(UserServiceImpl.java:51)
at com.vizaco.onlinecontrol.controller.UserController.createUser(UserController.java:112)
at com.vizaco.onlinecontrol.controller.UserController$$FastClassBySpringCGLIB$$2ef7ce5a.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:52)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:43)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.vizaco.onlinecontrol.controller.UserController$$EnhancerBySpringCGLIB$$9f848f41.createUser(<generated>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:137)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:776)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:806)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669)
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:146)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:199)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:105)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:550)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1128)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1062)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:215)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:110)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:113)
at org.eclipse.jetty.server.Server.handle(Server.java:507)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284)
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:237)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:240)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:93)
at org.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:53)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceRun.produceAndRun(ExecuteProduceRun.java:191)
at org.eclipse.jetty.util.thread.strategy.ExecuteProduceRun.run(ExecuteProduceRun.java:126)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:641)
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:559)
at java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:1)
在堆栈跟踪中,这两行之间没有列出Spring AOP类:
at com.vizaco.onlinecontrol.service.impl.UserServiceImpl.saveUser(UserServiceImpl.java:51)
at com.vizaco.onlinecontrol.controller.UserController.createUser(UserController.java:112)
您的依赖注入设置不正确.. Controller应该获得UserService的Spring Bean