我正在编写一个基于spring-boot的应用程序。在我的代码中,我有一个管理器类UManager,其中有一个方法保存。在这种方法中,有两个动作正在参与其中。第一个使用另一个管理器保存一些数据,第二个保存给予保存方法的数据。现在当其中一个动作失败时,两个动作都应该撤消。我假设,使用@Transactional注释将提供我需要的内容,就好像其中一个操作失败一样,整个事务将被回滚,并且不会对数据库进行任何更改。
@Component
public class UManager {
@Autowired
AManager aManager;
@Autowired
URepository uRepository;
... some stuff happening here
@Transactional
public U save(UBuilder uBuilder) {
aManager.save(something);
uRepository.save(uBuilder.build());
}
}
只要将@Transactional注释添加到save方法,应用程序就无法启动。我收到以下错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bController': Injection of autowired dependencies failed;
我做错了什么或者我错过了什么?
编辑: 这是堆栈跟踪:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: UManager BController.uManager; nested exception is java.lang.IllegalArgumentException: Can not set UManager field BController.uManager to com.sun.proxy.$Proxy102
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:764) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at org.springframework.boot.SpringApplication.doRun(SpringApplication.java:357) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:305) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1124) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1113) [spring-boot-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at RApplication.main(RApplication.java:44) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_72]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_72]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_72]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_72]
at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:467) [spring-boot-maven-plugin-1.3.1.RELEASE.jar:1.3.1.RELEASE]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_72]
编辑2: RApplication:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@SpringBootApplication
@EnableScheduling
@EnableTransactionManagement
public class RApplication {
public static void main(String[] args) {
SpringApplication.run(RaumbuchungApplication.class, args); //this is the line mentioned in the stacktrace
}
}
UManager:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import de.mischok.hfmw.raumbuchung.data.URepository;
import de.mischok.hfmw.raumbuchung.types.U;
import de.mischok.hfmw.raumbuchung.types.UBuilder;
@Component
public class UManager {
@Autowired
URepository uRepository;
@Transactional
public U save(UBuilder uBuilder){
}
}
BController:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import UManager;
@Controller
@RequestMapping("my/Path")
public class BController {
@Autowired
UManager uManager;
}
这些是代码的重要部分,因为其他部分不涉及问题。
答案 0 :(得分:2)
如果你没有使用xml spring配置,但是你有一个Application
类(我猜你发布的堆栈跟踪RApplication
),那么配置确保用@EnableTransactionManagement
<注释/ p>
e.g:
@Configuration
@ComponentScan
@EnableAutoConfiguration
@EnableJpaRepositories
@EnableTransactionManagement
public class Application {
//rest code goes here
}
修改强> 错误显示代理对象失败,您应该自动装入要注入的类(UManager)的接口而不是类本身。
e.g。
更改您的UManager
类以实现接口(当然也会向接口声明UManager
的任何公共方法)
public class UManager implements IUManager
并在你的bController
类中自动装配接口而不是类
public class BController {
@Autowired
IUManager uManager;
}
答案 1 :(得分:0)
您必须首先创建一个事务管理器,如下所示:
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
然后通过指定它来进行注释驱动:
<tx:annotation-driven transaction-manager = "txManager" />
现在您应该可以使用@Transactional
。
答案 2 :(得分:0)
所描述的错误看起来像来自另一个尝试Autowire
UManager的bean。我不是Spring的专家,但是当你把Transactional
放到DAO
类型的Component
时,你应该将bean声明为Repository
} bean而不是泛型Component
。 What's the difference between @Component, @Repository & @Service annotations in Spring?处的各种注释之间存在更多差异。