Reputation: 8116
I have a REST application that reads from a database repository.
I want to add a command line application that reads a CSV and imports the data to the database.
If I add another @SpringBootApplication
class that implements CommandLineRunner
to the project/jar, Spring starts it at the same time as my main server.
If I add a class that initialises the spring context itself, the jdbc url on the JPARepository uses the defaults instead of those from the spring boot properies
spring.datasource.url=jdbc:h2:file:./test;AUTO_SERVER=TRUE;DB_CLOSE_ON_EXIT=FALSE
@ComponentScan(basePackages = "com.test")
public class CsvImport {
@Autowired
private Repository repository;
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CsvImport.class);
context.start();
CsvImport csvImport = context.getBean(CsvImport.class);
File file = new File(args[0]);
if (file.isFile()) {
csvImport.importCsv(file);
}
context.stop();
}
private void importCsv(File file) {
....
....
Is there a better way to do this?
Upvotes: 0
Views: 742
Reputation: 8116
There are several steps required to get this working.
The first thing is that @SpringBootApplication
auto-scans any packages below it and will auto-start any CommandLineRunner that it finds so the command line application needs to be in a parallel package.
e.g.
- com
- test
- rest
- model
- repository
- controller
#RestSpringBoot.java
- Commands
#ImportCsv.java
The next thing is that since the command line application is in a parallel package you need to specify the scanning yourself.
There are 3 parts to this:
The first ensures the beans are created, the second ensures that the hibernate entities are created and the third ensures that the JPA classes are generated correctly.
The last part is to disable the start of the spring boot webserver otherwise you will have port conflicts.
This ends up with:
@SpringBootApplication
@ComponentScan(basePackageClasses = {Repository.class})
@EntityScan(basePackageClasses = {MyEntity.class})
@EnableJpaRepositories(basePackageClasses = {Repository.class})
public class CsvImport {
@Autowired
private RiskRepository repository;
public static void main(String[] args) {
SpringApplication app = new SpringApplication(CsvImport.class);
app.setBannerMode(Banner.Mode.OFF);
app.setWebApplicationType(WebApplicationType.NONE);
app.run(args);
}
@Override
public void run(String... args) throws Exception {
File file = new File(args[0]);
if (file.isFile()) {
importCsv(file);
}
}
private void importCsv(File file) {
....
....
Upvotes: 1