2

I've created simple REST application for books, based on Spring BOOT. I've created a /books/addBasicBooks mapping thats adding 3 basic books, just to have something in my repository to test, because I'm using in memory repository which is empty after starting application.

@RequestMapping(value = "/addBasicBooks")
public List<Book> addBasicBooks() {
    Book book = new Book.BookBuilder("W pustyni i w puszczy", "Henryk Sienkiewicz").pages(400).build();
    Book book1 = new Book.BookBuilder("Dziady IV", "Adam Mickiewicz").pages(300).build();
    Book book2 = new Book.BookBuilder("Krzyzacy", "Henryk Sienkiewicz").pages(900).build();

    bookRepository.save(book);
    bookRepository.save(book1);
    bookRepository.save(book2);

    return bookRepository.listAll();
}

I'm sure, there is a better way to do this. To add this books, when application is starting. I heard that Spring has some init ways, but i couldn't find anything.

nowszy94
  • 3,151
  • 4
  • 18
  • 33

3 Answers3

3

You could use a method prefixed with @PostConstruct

Something like that :

@Controller
@RequestMapping("/hello-world")
public class HelloWorldController {

    private List<Book> books;

    @RequestMapping(method=RequestMethod.GET)
    public List<Book> addBasicBooks() {
        return books;
    }

    @PostConstruct
    private void onInit(){
        Book book = new Book.BookBuilder("W pustyni i w puszczy", "Henryk Sienkiewicz").pages(400).build();
        Book book1 = new Book.BookBuilder("Dziady IV", "Adam Mickiewicz").pages(300).build();
        Book book2 = new Book.BookBuilder("Krzyzacy", "Henryk Sienkiewicz").pages(900).build();

        bookRepository.save(book);
        bookRepository.save(book1);
        bookRepository.save(book2);

        books = bookRepository.listAll();
    }
}

And you can play with a static List if you want to share the instance

vincent
  • 1,214
  • 12
  • 22
2

You can use Spring's @PostConstruct to construct your in-memory database after controller is instantiated. For more info see this link. See section '6.9.8. @PostConstruct and @PreDestroy'.

May be something like this:

    @PostConstruct
    public void init(){
        // initialize bookRepository
        Book book = new Book.BookBuilder("W pustyni i w puszczy", "Henryk Sienkiewicz").pages(400).build();
        Book book1 = new Book.BookBuilder("Dziady IV", "Adam Mickiewicz").pages(300).build();
        Book book2 = new Book.BookBuilder("Krzyzacy", "Henryk Sienkiewicz").pages(900).build();

        bookRepository.save(book);
        bookRepository.save(book1);
        bookRepository.save(book2);
    }

    @RequestMapping(value = "/addBasicBooks")
    public List<Book> addBasicBooks() {
        return bookRepository.listAll();
    }
justAbit
  • 4,226
  • 2
  • 19
  • 34
2

You are using Spring Boot what I tend to do for demo application is to add a bean of the type CommandLineRunner. I don't like to add it in @PostConstruct methods as there is not really a guarantee that your transactios are setup and it actually is part of your application not the controller.

Add the following to your application class.

@Bean
public CommandLineRunner dataInitializer(BookRepository br) {
    return new CommandLineRunner() {
        public void run (String... args) throws Exception {
            // initialize bookRepository
            Book book = new Book.BookBuilder("W pustyni i w puszczy", "Henryk Sienkiewicz").pages(400).build();
            Book book1 = new Book.BookBuilder("Dziady IV", "Adam Mickiewicz").pages(300).build();
            Book book2 = new Book.BookBuilder("Krzyzacy", "Henryk Sienkiewicz").pages(900).build();

            bookRepository.save(book);
            bookRepository.save(book1);
            bookRepository.save(book2);
        }
    };
}

This keeps your actual controllers and other code clean.

@Controller
@RequestMapping("/hello-world")
public class HelloWorldController {

    @RequestMapping(method=RequestMethod.GET)
    public List<Book> addBasicBooks() {
        return bookRepository.listAll();
    }
}

I would advice not to cache the books in the controller but to either use Spring Cache abstraction or (when using JPA) use your ORM's provider second level caching support to cache entities.

M. Deinum
  • 115,695
  • 22
  • 220
  • 224