Java 事务教程-测试回滚
我试图学习如何在JavaSpring中使用事务。我是一名java新手,请耐心听我说:-)我试图实现的单元测试是测试: 如果引发运行时异常,则回滚 我遇到的问题是 java.lang.NullPointerException 好了,开始。。我删去了一些代码以帮助提高可读性 TutorialTest.javaJava 事务教程-测试回滚,java,spring,transactions,dao,jdbctemplate,Java,Spring,Transactions,Dao,Jdbctemplate,我试图学习如何在JavaSpring中使用事务。我是一名java新手,请耐心听我说:-)我试图实现的单元测试是测试: 如果引发运行时异常,则回滚 我遇到的问题是 java.lang.NullPointerException 好了,开始。。我删去了一些代码以帮助提高可读性 TutorialTest.java @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = AppConfig.class, loader=
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class TutorialTest {
@Autowired
private Dao dao;
@Test
public void that_if_a_runtime_exception_is_thrown_transaction_rolledback(){
User u = new User();
u.setUsername("FAIL_TEST");
u.setPhone("0161");
u.setEmail("FAIL_TEST@gmail.com");
//dao.addUser(u); // -- this will insert if uncommented out so I know it works
OuterService os = new OuterService();
os.addUserThrowError(u);
}
}
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class OuterService {
@Autowired
private Dao dao;
@Transactional
public void addUserThrowError(User user) throws RuntimeException{
dao.addUser(user); // gives me a java.lang.NullPointerException?
throw new RuntimeException("This should roll back DB entry");
}
}
@Configuration
@EnableTransactionManagement
@ComponentScan(value = {"com.training.spring.tx.tutorial.dao",
"com.training.spring.tx.tutorial.service"})
public class AppConfig {
public DataSource dataSource() {
// Create a BasicDataSource object and configure database
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost/spring_training_tx");
dataSource.setUsername("training");
dataSource.setPassword("training");
return dataSource;
}
@Bean
public DataSourceTransactionManager transactionManager() {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource());
return transactionManager;
}
@Bean
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(transactionManager().getDataSource());
}
}
OuterService.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class TutorialTest {
@Autowired
private Dao dao;
@Test
public void that_if_a_runtime_exception_is_thrown_transaction_rolledback(){
User u = new User();
u.setUsername("FAIL_TEST");
u.setPhone("0161");
u.setEmail("FAIL_TEST@gmail.com");
//dao.addUser(u); // -- this will insert if uncommented out so I know it works
OuterService os = new OuterService();
os.addUserThrowError(u);
}
}
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class OuterService {
@Autowired
private Dao dao;
@Transactional
public void addUserThrowError(User user) throws RuntimeException{
dao.addUser(user); // gives me a java.lang.NullPointerException?
throw new RuntimeException("This should roll back DB entry");
}
}
@Configuration
@EnableTransactionManagement
@ComponentScan(value = {"com.training.spring.tx.tutorial.dao",
"com.training.spring.tx.tutorial.service"})
public class AppConfig {
public DataSource dataSource() {
// Create a BasicDataSource object and configure database
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost/spring_training_tx");
dataSource.setUsername("training");
dataSource.setPassword("training");
return dataSource;
}
@Bean
public DataSourceTransactionManager transactionManager() {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource());
return transactionManager;
}
@Bean
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(transactionManager().getDataSource());
}
}
豆子是在
AppConfig.java
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class TutorialTest {
@Autowired
private Dao dao;
@Test
public void that_if_a_runtime_exception_is_thrown_transaction_rolledback(){
User u = new User();
u.setUsername("FAIL_TEST");
u.setPhone("0161");
u.setEmail("FAIL_TEST@gmail.com");
//dao.addUser(u); // -- this will insert if uncommented out so I know it works
OuterService os = new OuterService();
os.addUserThrowError(u);
}
}
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class OuterService {
@Autowired
private Dao dao;
@Transactional
public void addUserThrowError(User user) throws RuntimeException{
dao.addUser(user); // gives me a java.lang.NullPointerException?
throw new RuntimeException("This should roll back DB entry");
}
}
@Configuration
@EnableTransactionManagement
@ComponentScan(value = {"com.training.spring.tx.tutorial.dao",
"com.training.spring.tx.tutorial.service"})
public class AppConfig {
public DataSource dataSource() {
// Create a BasicDataSource object and configure database
BasicDataSource dataSource = new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost/spring_training_tx");
dataSource.setUsername("training");
dataSource.setPassword("training");
return dataSource;
}
@Bean
public DataSourceTransactionManager transactionManager() {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource());
return transactionManager;
}
@Bean
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(transactionManager().getDataSource());
}
}
首先,引用
@ContextConfiguration
定义用于
确定如何加载和配置的ApplicationContext
集成测试
考虑一下如何在OuterService
上使用它。看起来对吗?OuterService
是否用于加载和配置集成测试的ApplicationCOntext
?除非我遗漏了一些重要的东西,否则答案是:不
那么什么是OuterService
?这是一种服务。你好像想把它当豆子用。什么是豆子?bean是一个对象,其生命周期由Spring管理。这包括bean类的实例化、对象的初始化、后处理,最后是对象的销毁
如果像这样创建对象
OuterService os = new OuterService();
那么春天就不在了。您创建了该对象,而Spring没有办法钩住它。因此,您不能期望Spring自动关联其字段
@Autowired
private Dao dao;
由于您尚未初始化该字段,它仍然是null
,这会导致NullPointerException
那么,我们如何获得一个由Spring管理的OuterService
bean呢?您可以为OuterService
声明@Bean
方法,或者使用@Component
或其任何专门化注释OuterService
,并对其所在的包进行组件扫描。然后将该bean注入到使用它的任何其他bean中。比如说,
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = AppConfig.class, loader=AnnotationConfigContextLoader.class)
public class TutorialTest {
@Autowired
private Dao dao;
@Autowired
private OuterService os;
然后可以直接使用该变量 Spring不参与
newouterservice()代码>查看Javadoc。Spring有非常好的文档。@ContextConfiguration
做什么?你如何在春季申报豆子?嗨,我已经更新了这个问题来帮助改进它。我还从标题中删除了spring。我已经包含了bean声明,答案非常简单:Spring不参与新的OuterService();因此不会将任何内容自动关联到该对象中。解释更长。阅读SpringIOC文档,它解释了所有这些。我已经看了文档,我还没有进一步弄清楚我需要做什么?从您的回复中,我想我需要将新的OuterService()与bean配置链接起来。上面的bean示例是XML格式的,我被告知要学习的不是。。