Почему я получаю исключение NullPointerException с @Autowired Repository в приложении Vaadin / SpringBoot? - PullRequest
3 голосов
/ 05 июня 2019

Я начинаю создавать веб-приложение с vaadin и весенней загрузкой. Я хочу создать сайт vaadin, который перечисляет данные с сервера MSSQL в сетке. Я всегда получаю NullPointerException при попытке использовать мой @Autowired CrudRepository.

Я прочитал много уроков по vaadin и spring, искал в Stackoverflow похожие проблемы, но пока не смог найти решение. В большинстве случаев с той же ошибкой люди забывают аннотировать репозиторий как @Repository или создают класс пользовательского интерфейса с новым ... Я проверил все эти распространенные ошибки, но не могу заставить свой код работать. Я также написал модульные тесты для базы данных, которая отлично работает!

Мой интерфейс CrudRepository с аннотацией @Repository

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

Мой пользовательский интерфейс, который должен показывать данные с помощью @Autowired репозитория

...
@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);
    }

}

Мой класс приложений:

...
@SpringBootApplication
public class IndikatorenbogenApplication {

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

Мой тест JUnit, в котором также используется репозиторий @Autowired (этот тест работает нормально и выводит данные из моей БД:

...

@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);
    }
}

Мой ожидаемый результат заключается в том, что 1178 строк, перечисленных тестом, отображаются в сетке в моем классе VaadinMainUI. Но вместо этого я получаю исключение NullPointerException при запуске моего приложения:

...
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

1 Ответ

5 голосов
/ 05 июня 2019

Проблема в вашем коде заключается в том, что вы используете bewohnerRepository в конструкторе VaadinMainUI. В Spring поля Autowired недоступны в конструкторах, так как внедрение полей выполняется после конструктора. Таким образом, вы должны изменить свой код соответственно. Вы можете, например, есть пользовательский метод, в котором вы делаете это и аннотируете его аннотацией @PostConstruct, которая заставляет Spring вызывать его после внедрения поля.

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

Или, в качестве альтернативы, вы можете автоматически связать bewohnerRepository в качестве параметра конструктора:

@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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...