org.springframework.beans.factory.BeanCreationException 与事务管理器
org.springframework.beans.factory.BeanCreationException with Transaction Manager
我一直在 Spring 应用程序上研究 Spring MVC,但我正在努力让它工作。
我的应用程序具有以下结构:
- @Entity Classes
- @Repository Classes(使用 @Transactional 进行查询)
- @RestfulController Classes(为了简化,我没有实现服务层)
我想使用 @Transactional 进行查询,但在 on server start 配置它时收到错误消息spring xml 文件.
WARN : org.springframework.web.context.support.XmlWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'calendarController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private br.com.milo.repository.CalendarRepository br.com.milo.controller.CalendarController.repository; nested exception is java.lang.IllegalArgumentException: Can not set br.com.milo.repository.CalendarRepository field br.com.milo.controller.CalendarController.repository to com.sun.proxy.$Proxy47
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:835)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:667)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:633)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:552)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:493)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5253)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5543)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1574)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1564)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
只有在我的 spring 配置文件中添加以下配置时才会发生此错误:
<tx:annotation-driven transaction-manager="transactionManager"/>
如果我删除这一行,问题就会消失,Restful 请求工作正常,但是,存储库方法不保存数据。在这种情况下,将显示以下消息(此错误发生在另一个控制器上,因为 Callendar 功能尚未完成。尽管如此,异常是相关的,因为它与事务有关):
Dec 29, 2015 5:03:45 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/milo] threw exception [Request processing failed; nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call] with root cause
javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:277)
at com.sun.proxy.$Proxy45.persist(Unknown Source)
at br.com.milo.repository.FarmRepository.save(FarmRepository.java:28)
at br.com.milo.controller.FarmController.insertFarm(FarmController.java:70)
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:497)
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.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
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:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at br.com.milo.security.CsrfHeaderFilter.doFilterInternal(CsrfHeaderFilter.java:34)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:120)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
这是我的 spring 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="br.com.milo" />
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/pages/**" location="/pages/" />
<resources mapping="/login/**" location="/login/" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="jsonMessageConverter"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</beans:bean>
<beans:bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="br.com.milo" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</beans:property>
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="org.postgresql.Driver" />
<beans:property name="url" value="jdbc:postgresql://localhost:5432/milo" />
<beans:property name="username" value="123" />
<beans:property name="password" value="123" />
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="myEmf" />
</beans:bean>
<!-- Just when I add this line the error above is shown -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans:beans>
这里是ClassCalendarController.java
package br.com.milo.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import br.com.milo.domain.Calendar;
import br.com.milo.domain.Owner;
import br.com.milo.domain.DTO.CalendarMonthDTO;
import br.com.milo.repository.CalendarRepository;
@RestController
@RequestMapping("/rest/calendar")
public class CalendarController {
private static final Logger logger = LoggerFactory.getLogger(CalendarController.class);
@Autowired
private CalendarRepository repository;
@RequestMapping(value = RestPaths.GET_CALENDAR, method = RequestMethod.GET)
public @ResponseBody Calendar getCalendar(@PathVariable("id") int id) {
logger.info("Start Get Calendar. ID=" + id);
return repository.findById(id);
}
@RequestMapping(value = RestPaths.LIST_CALENDARS, method = RequestMethod.GET)
public @ResponseBody List<Calendar> listCalendars() {
logger.info("Start List Calendars.");
List<Calendar> calendars = repository.list();
return calendars;
}
@RequestMapping(value = RestPaths.LIST_CALENDAR_BY_OWNER, method = RequestMethod.GET)
public @ResponseBody List<Calendar> listByOwner(@RequestBody Owner o) {
logger.info("Start List Calendars By Owner.");
List<Calendar> calendars = repository.listByType(o);
return calendars;
}
@RequestMapping(value = RestPaths.UPDATE_CALENDAR, method = RequestMethod.POST)
public @ResponseBody Calendar updateCalendar(@RequestBody Calendar calendar) {
logger.info("Start Update Calendar.");
repository.update(calendar);
return calendar;
}
@RequestMapping(value = RestPaths.INSERT_CALENDAR, method = RequestMethod.POST)
public @ResponseBody Calendar insertCalendar(@RequestBody Calendar calendar) {
logger.info("Start Insert Calendar.");
repository.save(calendar);
return calendar;
}
@RequestMapping(value = RestPaths.DELETE_CALENDAR, method = RequestMethod.PUT)
public @ResponseBody Calendar deleteCalendar(@PathVariable("id") int calendarId) {
logger.info("Start delete Calendar.");
Calendar calendar = repository.findById(calendarId);
repository.delete(calendar);
return calendar;
}
@RequestMapping(value = RestPaths.LIST_CALENDAR_BY_MONTH, method = RequestMethod.GET)
public @ResponseBody List<Calendar> listByMonth(@RequestBody CalendarMonthDTO calendarDTO) {
logger.info("Start List Calendar By Month.");
List<Calendar> calendars = repository.listByMonth(calendarDTO.getOwner(), calendarDTO.getYear(), calendarDTO.getMonth());
return calendars;
}
}
这里是classCalendarRepository.java
package br.com.milo.repository;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import br.com.milo.domain.Calendar;
import br.com.milo.domain.Owner;
@Repository
public class CalendarRepository implements br.com.milo.repository.Repository<Calendar, Owner>{
@PersistenceContext
private EntityManager entityManager;
@Override
@Transactional
public void save(Calendar calendar) {
entityManager.persist(calendar);
}
@Override
@Transactional
public void update(Calendar calendar) {
entityManager.merge(calendar);
}
@Override
@Transactional
public void delete(Integer id) {
this.delete(this.findById(id));
}
@Override
@Transactional
public void delete(Calendar calendar){
entityManager.remove(calendar);
}
@Override
@SuppressWarnings("unchecked")
public List<Calendar> list() {
Query query = entityManager.createQuery("from Calendar c order by c.calendarDate DESC");
return query.getResultList();
}
@Override
@SuppressWarnings("unchecked")
public List<Calendar> listByType(Owner o) {
if(o != null){
Query query = entityManager.createQuery("from Calendar c join c.ownerList o where o.name = :owner");
query.setParameter("owner", o.getName());
return query.getResultList();
}
return null;
}
@SuppressWarnings("unchecked")
public List<Calendar> listByMonth(Owner o, int year, int month) {
if(o != null){
Query query = entityManager.createQuery("from Calendar c join c.ownerList o "
+ "where o.name = :owner "
+ "and month(e.calendarDate)=:month "
+ "and year(e.calendarDate)=:year");
query.setParameter("owner", o.getName());
query.setParameter("month", month);
query.setParameter("year", year);
return query.getResultList();
}
return null;
}
@Override
public Calendar findById(Integer id) {
Calendar calendar = entityManager.find(Calendar.class, id);
return calendar;
}
}
提前感谢您关注我的问题!
您在 CalendarController
中的 repository
字段应该由接口定义,而不是 class。 Spring 围绕您的 CalendarRepository
创建了一个 Proxy,它实现了相同的接口,但不是 CalendarRepository
.
的子 class
这个问题是关于完全相同的问题:@Autowired return exception on UserDetails in Spring-security
You are trying to autowire your user details service by class, but that can't work, because the spring bean is actually a proxy created around that class (and not an instance of the class). The proxy will however implement all interfaces of the original bean, so injecting by interface is safe.
Exchange this line:
@Autowired
private MyCustomUserDetailsService myCustomUserDetailsService;
for this one:
@Autowired
private UserDetailsService myCustomUserDetailsService;
Read the section on Proxying Mechanisms in the Spring AOP to understand the details.
所以在你的情况下,你可以用你需要的方法创建一个新的 interface CalendarRepository
,然后在 class CalendarRepositoryImpl implements CalendarRepository
:
中实现
interface CalendarRepository extends br.com.milo.repository.Repository<Calendar, Owner>{
void save(Calendar calendar);
void update(Calendar calendar);
void delete(Integer id);
... (and all other methods you need)
}
@Repository
class CalendarRepositoryImpl implements CalendarRepository {
... (what you currently have in CalendarRepository)
}
class CalendarController {
@Autowired
CalendarRepository repository; // NOT CalendarRepositoryImpl
}
我一直在 Spring 应用程序上研究 Spring MVC,但我正在努力让它工作。
我的应用程序具有以下结构:
- @Entity Classes
- @Repository Classes(使用 @Transactional 进行查询)
- @RestfulController Classes(为了简化,我没有实现服务层)
我想使用 @Transactional 进行查询,但在 on server start 配置它时收到错误消息spring xml 文件.
WARN : org.springframework.web.context.support.XmlWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'calendarController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private br.com.milo.repository.CalendarRepository br.com.milo.controller.CalendarController.repository; nested exception is java.lang.IllegalArgumentException: Can not set br.com.milo.repository.CalendarRepository field br.com.milo.controller.CalendarController.repository to com.sun.proxy.$Proxy47
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
at org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:305)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:301)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:196)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:835)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:537)
at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:667)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:633)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:552)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:493)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1284)
at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1197)
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1087)
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:5253)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5543)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1574)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1564)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
只有在我的 spring 配置文件中添加以下配置时才会发生此错误:
<tx:annotation-driven transaction-manager="transactionManager"/>
如果我删除这一行,问题就会消失,Restful 请求工作正常,但是,存储库方法不保存数据。在这种情况下,将显示以下消息(此错误发生在另一个控制器上,因为 Callendar 功能尚未完成。尽管如此,异常是相关的,因为它与事务有关):
Dec 29, 2015 5:03:45 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [appServlet] in context with path [/milo] threw exception [Request processing failed; nested exception is javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call] with root cause
javax.persistence.TransactionRequiredException: No EntityManager with actual transaction available for current thread - cannot reliably process 'persist' call
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:277)
at com.sun.proxy.$Proxy45.persist(Unknown Source)
at br.com.milo.repository.FarmRepository.save(FarmRepository.java:28)
at br.com.milo.controller.FarmController.insertFarm(FarmController.java:70)
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:497)
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.invokeHandlerMethod(RequestMappingHandlerAdapter.java:806)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:729)
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:970)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:316)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:114)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:122)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:48)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:205)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:120)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at br.com.milo.security.CsrfHeaderFilter.doFilterInternal(CsrfHeaderFilter.java:34)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:120)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:64)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:53)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:91)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:213)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:176)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
这是我的 spring 配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="br.com.milo" />
<resources mapping="/resources/**" location="/resources/" />
<resources mapping="/pages/**" location="/pages/" />
<resources mapping="/login/**" location="/login/" />
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<beans:bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<beans:property name="messageConverters">
<beans:list>
<beans:ref bean="jsonMessageConverter"/>
</beans:list>
</beans:property>
</beans:bean>
<beans:bean id="jsonMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
</beans:bean>
<beans:bean id="myEmf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<beans:property name="dataSource" ref="dataSource" />
<beans:property name="packagesToScan" value="br.com.milo" />
<beans:property name="jpaVendorAdapter">
<beans:bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</beans:property>
<beans:property name="jpaProperties">
<beans:props>
<beans:prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</beans:prop>
</beans:props>
</beans:property>
</beans:bean>
<beans:bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<beans:property name="driverClassName" value="org.postgresql.Driver" />
<beans:property name="url" value="jdbc:postgresql://localhost:5432/milo" />
<beans:property name="username" value="123" />
<beans:property name="password" value="123" />
</beans:bean>
<beans:bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<beans:property name="entityManagerFactory" ref="myEmf" />
</beans:bean>
<!-- Just when I add this line the error above is shown -->
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans:beans>
这里是ClassCalendarController.java
package br.com.milo.controller;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import br.com.milo.domain.Calendar;
import br.com.milo.domain.Owner;
import br.com.milo.domain.DTO.CalendarMonthDTO;
import br.com.milo.repository.CalendarRepository;
@RestController
@RequestMapping("/rest/calendar")
public class CalendarController {
private static final Logger logger = LoggerFactory.getLogger(CalendarController.class);
@Autowired
private CalendarRepository repository;
@RequestMapping(value = RestPaths.GET_CALENDAR, method = RequestMethod.GET)
public @ResponseBody Calendar getCalendar(@PathVariable("id") int id) {
logger.info("Start Get Calendar. ID=" + id);
return repository.findById(id);
}
@RequestMapping(value = RestPaths.LIST_CALENDARS, method = RequestMethod.GET)
public @ResponseBody List<Calendar> listCalendars() {
logger.info("Start List Calendars.");
List<Calendar> calendars = repository.list();
return calendars;
}
@RequestMapping(value = RestPaths.LIST_CALENDAR_BY_OWNER, method = RequestMethod.GET)
public @ResponseBody List<Calendar> listByOwner(@RequestBody Owner o) {
logger.info("Start List Calendars By Owner.");
List<Calendar> calendars = repository.listByType(o);
return calendars;
}
@RequestMapping(value = RestPaths.UPDATE_CALENDAR, method = RequestMethod.POST)
public @ResponseBody Calendar updateCalendar(@RequestBody Calendar calendar) {
logger.info("Start Update Calendar.");
repository.update(calendar);
return calendar;
}
@RequestMapping(value = RestPaths.INSERT_CALENDAR, method = RequestMethod.POST)
public @ResponseBody Calendar insertCalendar(@RequestBody Calendar calendar) {
logger.info("Start Insert Calendar.");
repository.save(calendar);
return calendar;
}
@RequestMapping(value = RestPaths.DELETE_CALENDAR, method = RequestMethod.PUT)
public @ResponseBody Calendar deleteCalendar(@PathVariable("id") int calendarId) {
logger.info("Start delete Calendar.");
Calendar calendar = repository.findById(calendarId);
repository.delete(calendar);
return calendar;
}
@RequestMapping(value = RestPaths.LIST_CALENDAR_BY_MONTH, method = RequestMethod.GET)
public @ResponseBody List<Calendar> listByMonth(@RequestBody CalendarMonthDTO calendarDTO) {
logger.info("Start List Calendar By Month.");
List<Calendar> calendars = repository.listByMonth(calendarDTO.getOwner(), calendarDTO.getYear(), calendarDTO.getMonth());
return calendars;
}
}
这里是classCalendarRepository.java
package br.com.milo.repository;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import br.com.milo.domain.Calendar;
import br.com.milo.domain.Owner;
@Repository
public class CalendarRepository implements br.com.milo.repository.Repository<Calendar, Owner>{
@PersistenceContext
private EntityManager entityManager;
@Override
@Transactional
public void save(Calendar calendar) {
entityManager.persist(calendar);
}
@Override
@Transactional
public void update(Calendar calendar) {
entityManager.merge(calendar);
}
@Override
@Transactional
public void delete(Integer id) {
this.delete(this.findById(id));
}
@Override
@Transactional
public void delete(Calendar calendar){
entityManager.remove(calendar);
}
@Override
@SuppressWarnings("unchecked")
public List<Calendar> list() {
Query query = entityManager.createQuery("from Calendar c order by c.calendarDate DESC");
return query.getResultList();
}
@Override
@SuppressWarnings("unchecked")
public List<Calendar> listByType(Owner o) {
if(o != null){
Query query = entityManager.createQuery("from Calendar c join c.ownerList o where o.name = :owner");
query.setParameter("owner", o.getName());
return query.getResultList();
}
return null;
}
@SuppressWarnings("unchecked")
public List<Calendar> listByMonth(Owner o, int year, int month) {
if(o != null){
Query query = entityManager.createQuery("from Calendar c join c.ownerList o "
+ "where o.name = :owner "
+ "and month(e.calendarDate)=:month "
+ "and year(e.calendarDate)=:year");
query.setParameter("owner", o.getName());
query.setParameter("month", month);
query.setParameter("year", year);
return query.getResultList();
}
return null;
}
@Override
public Calendar findById(Integer id) {
Calendar calendar = entityManager.find(Calendar.class, id);
return calendar;
}
}
提前感谢您关注我的问题!
您在 CalendarController
中的 repository
字段应该由接口定义,而不是 class。 Spring 围绕您的 CalendarRepository
创建了一个 Proxy,它实现了相同的接口,但不是 CalendarRepository
.
这个问题是关于完全相同的问题:@Autowired return exception on UserDetails in Spring-security
You are trying to autowire your user details service by class, but that can't work, because the spring bean is actually a proxy created around that class (and not an instance of the class). The proxy will however implement all interfaces of the original bean, so injecting by interface is safe.
Exchange this line:
@Autowired private MyCustomUserDetailsService myCustomUserDetailsService;
for this one:
@Autowired private UserDetailsService myCustomUserDetailsService;
Read the section on Proxying Mechanisms in the Spring AOP to understand the details.
所以在你的情况下,你可以用你需要的方法创建一个新的 interface CalendarRepository
,然后在 class CalendarRepositoryImpl implements CalendarRepository
:
interface CalendarRepository extends br.com.milo.repository.Repository<Calendar, Owner>{
void save(Calendar calendar);
void update(Calendar calendar);
void delete(Integer id);
... (and all other methods you need)
}
@Repository
class CalendarRepositoryImpl implements CalendarRepository {
... (what you currently have in CalendarRepository)
}
class CalendarController {
@Autowired
CalendarRepository repository; // NOT CalendarRepositoryImpl
}