Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I get NullPointerException with @Autowired Repository in Vaadin / SpringBoot application?

I am starting to build a web application with vaadin and spring boot. I want to create a vaadin site which lists data from a MSSQL Server in a grid. I always get NullPointerException when trying to use my @Autowired CrudRepository.

I have read through a lot of vaadin and spring tutorials, searched Stackoverflow for similar problems but could not find a solution, yet. In most cases with same error, people forgot to annotate the Repository as @Repository or created the UI class with new ... I checked all that common mistakes but I can't get my code working. I also wrote a unit tests against the database which works fine!

My CrudRepository Interface with @Repository annotation

...
@Repository
public interface BewohnerRepository extends CrudRepository<Bewohner, Integer>{
    ...
}
...

My UI that should show the data with @Autowired repository

...
@Route("")
@SpringComponent
@Configurable
public class VaadinMainUI extends VerticalLayout {

    @Autowired
    private BewohnerRepository bewohnerRepository;

    public VaadinMainUI() {     
        Grid<Bewohner> grid = new Grid<Bewohner>(Bewohner.class);
        Iterable<Bewohner> bewohnerList = bewohnerRepository.findAll();
        grid.setItems((Collection<Bewohner>) bewohnerList);
        add(grid);
    }

}

My Applications main class:

...
@SpringBootApplication
public class IndikatorenbogenApplication {

    public static void main(String[] args) {
        SpringApplication.run(IndikatorenbogenApplication.class, args);
    }
}

My JUnit Test that also uses @Autowired repository (this test works fine and Lists data from my DB:

...

@RunWith(SpringRunner.class)
@SpringBootTest
public class BewohnerRepositoryTest {

    @Autowired
    private BewohnerRepository bewohnerRepository;

    @Test
    public void testInjectedComponentsNotNull() {
        assertNotNull(bewohnerRepository);
    }

    @Test
    public void testFetchData(){
        Iterable<Bewohner> bewohnerList = bewohnerRepository.findAll();
        int count = 0;
        for(Bewohner bewohner : bewohnerList){          
            count++;
            System.out.println(count +": " + bewohner);
        }
        assertEquals(count, 1178);
    }
}

My expected rsult is that the 1178 lines listed by the test are displayed in the grid in my VaadinMainUI class. But instead of that I get a NullPointerException when starting my application:

...
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [de.lim.tap.indikatorenbogen.ui.VaadinMainUI]: Constructor threw exception; nested exception is java.lang.NullPointerException
    at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:184)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1295)
    ... 23 more
like image 805
tigu Avatar asked Dec 23 '22 23:12

tigu


1 Answers

The issue in your code is that you are using bewohnerRepository in the constructor VaadinMainUI. In Spring Autowired fields are not available in constructors as field injection is done after constructor. So you need to change your code accordingly. You can e.g. have custom method where you do this and annotate it with @PostConstruct annotation, which makes Spring call it after field injection.

@PostConstruct
private void doGridSetup() {
Grid<Bewohner> grid = new Grid<Bewohner>(Bewohner.class);
        Iterable<Bewohner> bewohnerList = bewohnerRepository.findAll();
        grid.setItems((Collection<Bewohner>) bewohnerList);
        add(grid);
}

Or, as annother alternative you can autowire bewohnerRepository as constructor parameter:

@Autowire
public VaadinMainUI(BewohnerRepository bewohnerRepository) {
Grid<Bewohner> grid = new Grid<Bewohner>(Bewohner.class);
        Iterable<Bewohner> bewohnerList = bewohnerRepository.findAll();
        grid.setItems((Collection<Bewohner>) bewohnerList);
        add(grid);
}
like image 76
Tatu Lund Avatar answered Dec 31 '22 13:12

Tatu Lund