I am very new to webapp development in general and Spring framework in particular. I am following this Spring JDBC Transactions tutorial But instead of accessing the db service from only one class, I wish to access it from multiple classes.
In the tutorial the service is defined like this
public class BookingService {
@Autowired
JdbcTemplate jdbcTemplate;
@Transactional
public void book(String... persons) {
for (String person : persons) {
System.out.println("Booking " + person + " in a seat...");
jdbcTemplate.update("insert into BOOKINGS(FIRST_NAME) values (?)", person);
}
};
public List<String> findAllBookings() {
return jdbcTemplate.query("select FIRST_NAME from BOOKINGS", new RowMapper<String>()
@Override
public String mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getString("FIRST_NAME");
}
});
}
}
These are the Beans
@Configuration
@EnableTransactionManagement
@EnableAutoConfiguration
public class Application {
@Bean
BookingService bookingService() {
return new BookingService();
}
@Bean
DataSource dataSource() {
return new SimpleDriverDataSource() {{
setDriverClass(org.h2.Driver.class);
setUsername("sa");
setUrl("jdbc:h2:mem");
setPassword("");
}};
}
@Bean
JdbcTemplate jdbcTemplate(DataSource dataSource) {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
System.out.println("Creating tables");
jdbcTemplate.execute("drop table BOOKINGS if exists");
jdbcTemplate.execute("create table BOOKINGS(" +
"ID serial, FIRST_NAME varchar(5) NOT NULL)");
return jdbcTemplate;
}
They instantiated the service in only the Application class and did all the transactions there
ApplicationContext ctx = SpringApplication.run(Application.class, args);
BookingService bookingService = ctx.getBean(BookingService.class);
//bookingService.doStuff()
In my test project, I copied the same Bean definitions but I performed the transactions in multiple classes.
public class foo {
ApplicationContext ctx = new AnnotationConfigApplicationContext(Application.class);
BookingService bookingService = ctx.getBean(BookingService.class);
bookingService.book(...);
// some other stuff
}
public class bar {
ApplicationContext ctx = new AnnotationConfigApplicationContext(Application.class);
BookingService bookingService = ctx.getBean(BookingService.class);
bookingService.findAllBookings(...);
// some other stuff
}
It seems that when I perform all transactions in one class only (for example, book and find in foo class) it performs as expected. But when I try to separate them into multiple classes it doesn't behave as expected. If I perform the book in foo, I cannot find in bar. What concept am I missing? Am I instantiating multiple instances of the datasource and jdbctemplate because I instantiated the service multiple times. But I thought Spring handles the injection? And since there is only one physical database then there would only be one instance of datasource and jdbctemplate. What concept did I misunderstood? Please help and point me to the right direction. Thanks.
You need to inject your dependencies, for example:
public class Foo {
@Autowired
private BookingService bookingService;
public doStuff() {
bookingService.book(...);
// some other stuff
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.