Search code examples
springexceptioncollectionsjavabeanscode-injection

Spring Beans: Can you add elements into an injected list?


I am quite new at Spring Beans and I'm trying to build a rest controller that implements the CRUD operations.

I have a config file that has a @Bean that returns a list of Book type:

@Configuration
public class BookConfig {

    @Bean
    public static List<Book> books() {
        return Arrays.asList(
            new Book(1, "ABC", "Author ABC"),
            new Book(2, "DEF", "Author DEF"),
            new Book(3, "GHI", "Author GHI"));
    }
}

And the rest controller in which I constructor-injected the above Bean:

@RestController
@RequestMapping("/api/v1/books")
public class BookRestController {

    private List<Book> books;

    @Autowired
    public BookRestController(List<Book> books) {
        this.books = books;
    }

    @PostMapping("")
    public void registerBook(@RequestBody Book book) {
        books.add(book); // this throws **UnsupportedOperationException**
    }
}

At the POST method I try to add my book that comes from the request the my list of books, but I get an UnsupportedOperationException.

Is it just not possible to alter an injected collection or how should it be done?


Solution

  • We can achieve this with small steps again if this is for tutorial purposes.

    • You can create a class that hosts the list.
    • we can provide getter and setter methods in that class.
    • Inject this class afterward.

    Class would become

    //BadNamedCLass
    DataManager {
     private final List<Book> books = ArrayList<Book>();
     {
     // init block to add item to books if you want during initialization
     }
    // getters
    //setters
    }
    

    Config becomes:

    @Configuration
    public class BookConfig {
    
        @Bean
        public DataManager dataManager() {
            return new DataManager();
        }
    }
    

    Controller code becomes

    ...
        @Autowired
        public BookRestController(DataManager dataManager) {
            this.dataManager= dataManager;
        }
    ...
    

    For the exception please follow this link