Vaadin EntityManager NullReferenceException

Я пытаюсь заставить программу работать в vaadin и spring-boot, но не могу заставить работать EntityManager. Получение исключения NullReferenceException

Для начала, это моя первая попытка сделать что-то с использованием Spring-boot и Vaadin. Я пытаюсь заставить EntityManager работать, но получаю исключение NullReferenceException. Кажется, мой EntityManager выдает исключение, но я не могу найти примеров того, как его правильно использовать. Я думал об использовании EntityManagerFactory, но опять же, нигде нет примеров. Метод findAll() работает, поэтому я не знаю, что делать.

У меня есть интерфейс Repository_Room

public interface Repository_Room
{
    void save(Room room);

    void delete(Room room);

    void update(Room room);

    List<Room> findAll();

    List<Course> getCourses(Room room);
}

Реализация в классе Repository_Room_Impl

@Transactional
@Repository
public class Repository_Room_Impl implements Repository_Room{

    @PersistenceContext
    private EntityManager em;

    public Repository_Room_Impl()
    {

    }

    @Override
    public List<Room> findAll() {
        return em.createQuery("select n from " + Room.class.getSimpleName() + " n").getResultList();
    }

    @Override
    public void save(Room room) {
        em.persist(room);
    }

    public void delete(Room room) {
        em.remove(em.find(Room.class, room.getId()));
    }

    public void update(Room room) {
        em.merge(em);
    }

    public List<Course> getCourses(Room room)
    {
        List<Course> courses = em.createQuery("select n from " + Course.class.getSimpleName() + " n WHERE n.Room = :roomID", Course.class)
                .setParameter("roomID", room.getId())
                .getResultList();
        return courses;
    }
}

Попытка использовать репозиторий в моей форме для добавления нового элемента

@SpringComponent
@UIScope
public class Form_Room extends VerticalLayout {

    private Room room;

    private Reloader reloader;

    private TextField val_id;
    private TextField val_name;
    private TextField val_level;

    private Binder<Room> binder;

    @Autowired
    private Repository_Room repository;

    public Form_Room()
    {
        binder = new Binder<>(Room.class);

        val_id = new TextField("ID:");
        val_name = new TextField("Name:");
        val_level = new TextField(("Level:"));

        binder.forField(val_id)
                .withConverter(
                        new StringToIntegerConverter("Must enter a number"))
                .bind(Room::getId, Room::setId);

        binder.forField(val_name).bind(Room::getName, Room::setName);

        binder.forField(val_level)
                .withConverter(
                        new StringToIntegerConverter("Must enter a number"))
                .bind(Room::getLevel, Room::setLevel);

        add(val_id);
        add(val_name);
        add(val_level);
    }

    public Room getRoom() {
        return room;
    }

    public void setRoom(Room room) {
        if (room == null) {
            this.room = null;
        }
        else {
            this.room = room;
            binder.readBean(this.room);
        }
    }

    public Reloader getReloader() {
        return reloader;
    }

    public void setReloader(Reloader reloader) {
        this.reloader = reloader;
    }

    public void updateRoom()
    {
        try
        {
            if (room == null)
            {
                repository.save(this.room);
                System.out.println("Created");
            }
            else
            {
                binder.writeBean(this.room);
                repository.update(this.room);
                System.out.println("Updated");
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }
}

Эта форма создана на мой взгляд

@Route(value = "rooms")
public class View_CRUD_Room extends VerticalLayout implements Reloader{

    @Autowired
    private Repository_Room repository;

    @Autowired
    private Form_Room form;

    private Grid<Room> grid;
    private Button button_view;
    private Button button_remove;
    private Button button_execute;
    private HorizontalLayout buttonLayout;

    private Room selected;

    @PostConstruct
    private void init(){
        form = new Form_Room();
        grid = new Grid<>();
        button_view = new Button();
        button_remove = new Button();
        buttonLayout = new HorizontalLayout();
        selected = null;

        button_execute = new Button();
        button_execute.setText("Végrehajt");

        button_view.setText("Részletek");
        button_remove.setText("Töröl");
        buttonLayout.add(button_view);
        buttonLayout.add(button_remove);

        form.setVisible(true);

        button_execute.addClickListener(event -> {
            form.updateRoom();
        });

        button_view.addClickListener(event -> {
            // Display details
        });

        button_remove.addClickListener(event -> {
            // Display form with confirmation message and YesNo buttons
        });

        List<Room> list = repository.findAll();
        grid.setItems(repository.findAll());
        grid.addColumn(Room::getId).setHeader("Id");
        grid.addColumn(Room::getName).setHeader("Name");
        grid.addColumn(Room::getLevel).setHeader("Terem");
        grid.asSingleSelect().addValueChangeListener(selectionEvent -> {
            if (selectionEvent.getValue() != null) {
                selected = selectionEvent.getValue();
                form.setRoom(selected);
            } else {
                selected = null;
                form.setRoom(selected);
            }
        });
        add(new Text("Termek"));
        add(grid);
        add(buttonLayout);
        add(form);
        add(button_execute);
    }

    @Override
    public void processRefresh() {
        grid.setItems(repository.findAll());
    }
}

StackTrace печатает следующее:

java.lang.NullPointerException
    at com.example.beadando.repository.Impl.Repository_Room_Impl.save(Repository_Room_Impl.java:26)
    at com.example.beadando.component.Form_Room.updateRoom(Form_Room.java:93)
    at com.example.beadando.view.View_CRUD_Room.lambda$init$9b1b5227$1(View_CRUD_Room.java:55)
    at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:205)
    at com.vaadin.flow.component.ComponentEventBus.handleDomEvent(ComponentEventBus.java:373)
    at com.vaadin.flow.component.ComponentEventBus.lambda$addDomTrigger$dd1b7957$1(ComponentEventBus.java:264)
    at com.vaadin.flow.internal.nodefeature.ElementListenerMap.lambda$fireEvent$2(ElementListenerMap.java:420)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at com.vaadin.flow.internal.nodefeature.ElementListenerMap.fireEvent(ElementListenerMap.java:420)
    at com.vaadin.flow.server.communication.rpc.EventRpcHandler.handleNode(EventRpcHandler.java:59)
    at com.vaadin.flow.server.communication.rpc.AbstractRpcInvocationHandler.handle(AbstractRpcInvocationHandler.java:64)
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocationData(ServerRpcHandler.java:387)
    at com.vaadin.flow.server.communication.ServerRpcHandler.lambda$handleInvocations$1(ServerRpcHandler.java:368)
    at java.util.ArrayList.forEach(ArrayList.java:1249)
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:368)
    at com.vaadin.flow.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:310)
    at com.vaadin.flow.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:89)
    at com.vaadin.flow.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:40)
    at com.vaadin.flow.server.VaadinService.handleRequest(VaadinService.java:1507)
    at com.vaadin.flow.server.VaadinServlet.service(VaadinServlet.java:242)
    at com.vaadin.flow.spring.SpringServlet.service(SpringServlet.java:81)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712)
    at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459)
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:352)
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
    at org.springframework.web.servlet.mvc.ServletForwardingController.handleRequestInternal(ServletForwardingController.java:141)
    at org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:177)
    at org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:52)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:908)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:660)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:836)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1747)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

Я изменил метод setRoom(), чтобы попытаться добавить новый элемент, не имея дело с моими текстовыми полями. Получение NullReferenceException в форме при попытке вызвать мой метод updateRoom(). Пожалуйста, направьте меня в правильном направлении .. Спасибо!

попробуйте заменить аннотацию "@Repository" просто аннотацией "@Component" и посмотрите, работает ли это

Toerktumlare 08.06.2019 04:00

Это не помогло, к сожалению. Тем не менее то же самое NullReferenceException вызывается в em.persist() в репозитории.save()

Flashcap 08.06.2019 07:40

На первый взгляд в вашем коде есть несколько проблем. Например, вы создаете репозиторий в Form_Room с помощью new, и у вас есть @Autowired в этом классе. Вы должны реорганизовать код. Также я вижу, что вы новее читаете или устанавливаете bean-компонент в Binder, поэтому все, что вы редактируете, не будет сохранено, поскольку в вашей форме нет bean-компонента.

Tatu Lund 08.06.2019 09:41

Чтобы добавить к тому, что сказал Тату, причина, по которой findAll() работает, заключается в том, что, по вашему мнению, вы не инициализируете репозиторий вручную, вместо этого позволяя Spring внедрить его для вас и в то же время внедрить диспетчер сущностей в репозиторий. Однако в вашей форме вы инициализируете ее вручную, что означает, что Spring больше не управляет ею и не может внедрить ваш менеджер сущностей вместо вас.

Erik Lumme 08.06.2019 10:02
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
3
4
94
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Извините, я был слишком быстр, когда смотрел раньше.

Но это ваша проблема, вы сами создаете автосвязанные классы, а не позволяете Spring создавать их за вас.

@Autowired
private Repository_Room repository;

public Form_Room() {
    repository = new Repository_Room_Impl(); //remove this line

    //rest of the code
}

И здесь вы делаете это снова в своем представлении:

@Route(value = "rooms")
public class View_CRUD_Room extends VerticalLayout implements Reloader {

@PostConstruct
private void init(){
    form = new Form_Room(); //remove this line

    //rest of the code
}

Вы видите, что autowire — это то, что называется внедрением зависимостей. Это причудливое слово для того, чтобы сказать, что «фреймворк» (в данном случае spring) сделает за вас все экземпляры классов.

Spring сделает «новое» за вас. И внедрите класс во время выполнения, чтобы вы могли использовать его, чтобы вам не приходилось этого делать. Spring также перед тем, как сделать «новый RepositoryImpl()», проверит, какие зависимости имеет этот класс, и увидит, что ему нужен EntityManager, и автоматически создаст экземпляр для вас и поместит его в RepositoryImpl.

В этом весь смысл использования Autowire, что вам не нужно делать что-то новое. Вы просто должны верить, что там будет класс, когда вы его используете.

Затем некоторые другие указатели о вашем коде.

В java мы используем корпус верблюда, поэтому вместо «Repository_Room» должно быть «RepositoryRoom», то же самое касается «Repository_Room_Impl», должно быть «RepositoryRoomImpl».

Спасибо за объяснение, теперь стало понятно, как работает автосвязывание, но даже если я удалю эту строку и позволю репозиторию автоматически связать, я все равно получаю свое исключение в том же месте (repository.update), но я не могу понять, почему , после выбора строки я вызываю setRoom, чтобы установить переменную, используемую при обновлении.

Flashcap 09.06.2019 09:59

Восстановил setRoom к предыдущему коду и попытался протестировать только метод обновления, при котором существующий элемент изменяется с использованием моей формы, но он по-прежнему генерирует исключение.

Flashcap 09.06.2019 10:53

когда вы отлаживаете, это "Repository_Room" имеет значение null? или EntityManager имеет значение null, или это this.room имеет значение null?

Toerktumlare 09.06.2019 14:49

репозиторий нулевой. this.room имеет ценность. Таким образом, исключение выдается перед попыткой слияния.

Flashcap 09.06.2019 19:07

если вы запустите приложение в режиме отладки, вы сможете увидеть в журналах, удастся ли ему найти ваш репозиторий и создать его.

Toerktumlare 09.06.2019 19:51

Все, что я получаю в отладке, это следующее: 2019-06-09 20:22:01.792 DEBUG 5148 --- [nio-8080-exec-4] osweb.servlet.DispatcherServlet: POST "/?vr=uidl&v-uiId =0", параметры = {маскированные} 2019-06-09 20:22:01.793 ОТЛАДКА 5148 --- [nio-8080-exec-4] oswshandler.SimpleUrlHandlerMapping : Сопоставлено с org.springframework.web.servlet.mvc. ServletForwardingControl‌​ler@49bb808f 2019-06-09 20:22:01.807 DEBUG 5148 --- [nio-8080-exec-4] osweb.servlet.DispatcherServlet: выполнено 200 OK

Flashcap 09.06.2019 20:23

2019-06-09 20:22:01.843 ОТЛАДКА 5148 --- [nio-8080-exec-9] osweb.servlet.DispatcherServlet: POST "/?vr=uidl&v-uiId=0", параметры = {masked} 2019 -06-09 20:22:01.843 DEBUG 5148 --- [nio-8080-exec-9] oswshandler.SimpleUrlHandlerMapping : Сопоставлено с org.springframework.web.servlet.mvc.ServletForwardingControl‌​ler@49bb808f

Flashcap 09.06.2019 20:24

Странно то, что, на мой взгляд, это работает, но не в форме, несмотря на то, что в обоих местах автоподключение.

Flashcap 09.06.2019 20:40

я обновил свой ответ, вам нужно удалить еще одну строку

Toerktumlare 09.06.2019 20:51

Боже. Вы были правы, я не заметил, что это тоже было автоматическим. Получил новое исключение, но я надеюсь, что смогу решить это. Неизвестный объект: com.sun.proxy.$Proxy87. Спасибо, я стараюсь :)

Flashcap 09.06.2019 21:05

не беспокойтесь, пожалуйста, примите мой ответ как правильный и задайте новый вопрос, если вы застряли

Toerktumlare 09.06.2019 23:09

Другие вопросы по теме