Как правильно сохранить Vaadin CheckBox в JPA?

Я ищу пример Vaadin, но я вообще не нашел использования Checkbox для JPA.

Я пытаюсь это сделать, но это работает, только если я один раз нажимаю на флажок, если снова нажать на то же поле прерывается

private Grid createGrid() {
    grid = new Grid<>();
    ListDataProvider<User> dataProvider = DataProvider.ofCollection(userRepository.findAll());
    grid.setDataProvider(dataProvider);
    grid.setHeight("100%");
    grid.setMaxWidth("840px");

    grid.addColumn(new ComponentRenderer<>(this::createUserInfo)).setWidth(UIUtils.COLUMN_WIDTH_XL);
    grid.addComponentColumn(u -> {
        Checkbox c = new Checkbox();
        c.getStyle().set("font-size", "24px");
        c.setValue(u.isAnwesend());
        c.addValueChangeListener(click -> {
            changeIsAnwesend(u);
        });

        return c;
    })
            .setFlexGrow(0)
            .setWidth(UIUtils.COLUMN_WIDTH_XS);

    grid.addThemeVariants(GridVariant.LUMO_NO_ROW_BORDERS);

    return grid;
}

private void changeIsAnwesend(User user) {
    user.setAnwesend(!user.isAnwesend());
    userRepository.save(user);
}

Это ошибки:

org.springframework.orm.ObjectOptimisticLockingFailureException: Object of class [com.softwareaustria.backend.data.entity.User] with identifier [21]: optimistic locking failed; nested exception is org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.softwareaustria.backend.data.entity.User#21]

Caused by: org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect) : [com.softwareaustria.backend.data.entity.User#21] *

Прежде чем я начну исследовать Hibernate, я спрашиваю, как правильно и обычно сохранять Checkbox в JPA в Vaadin.

Большое спасибо!

РЕШЕНО:

Спасибо за предложение @Kaspar Scherrer и @Simon Martinelli

Я меняю параметры метода на (User user, Grid grid) и добавить после userRepository.save (пользователь);

  grid.setItems(userRepository.findAll());

и наконец работа!

Это рабочий код:

private Grid createGrid() {
        grid = new Grid<>();
        ListDataProvider<User> dataProvider = DataProvider.ofCollection(userRepository.findAll());
        grid.setDataProvider(dataProvider);
        grid.setHeight("100%");
        grid.setMaxWidth("840px");

        grid.addColumn(new ComponentRenderer<>(this::createUserInfo)).setWidth(UIUtils.COLUMN_WIDTH_XL);
        grid.addComponentColumn(u -> {
            Checkbox checkbox = new Checkbox();
            checkbox.getStyle().set("font-size", "24px");
            checkbox.setValue(u.isAnwesend());
            checkbox.addValueChangeListener(click -> {
                changeIsAnwesend(u, grid);
            });

            return checkbox;
        })
                .setFlexGrow(0)
                .setWidth(UIUtils.COLUMN_WIDTH_XS);

        grid.addThemeVariants(GridVariant.LUMO_NO_ROW_BORDERS);

        return grid;
    }

       private void changeIsAnwesend(User user, Grid grid) {
    user.setAnwesend(!user.isAnwesend());
    userRepository.save(user);
    refresh();
}

private void refresh() {
    grid.setItems(userRepository.findAll());
}

ИМХО это неправильный подход. Упомянутая вами проблема, скорее всего, столкнется с вами только во второй раз, когда вы переключите bool на пользователя? Итак, теперь вы исправили свое сохранение на устаревшем объекте для следующего раза, если неизменный объект не будет изменен другим пользователем. Я думаю, вам следует перезагрузить пользователя в начале changeIsAnwesend и убедиться, что «переключение» является намерением пользователя (а не просто отрицанием значения из последней увиденной сетки). Затем перезагрузите сетку и т. д., как у вас.

cfrick 25.06.2019 09:59
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
163
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Вы получаете ObjectOptimisticLockingFailureException, что означает, что ваш объект User уже был изменен в базе данных.

Вы должны перезагрузить объект из базы данных перед установкой флага anwesend.

я рад помочь

Simon Martinelli 24.06.2019 20:13
Ответ принят как подходящий

Я согласен с ответом Саймона Мартинелли. Ваши данные устарели (не обновлены) и требуют перезагрузки.
Вот как вы могли бы это сделать.

checkbox.addValueChangeListener(click -> {
    changeIsAnwesend(u, grid);
});

....

private void changeIsAnwesend(User user, Grid grid) {
    user.setAnwesend(!user.isAnwesend());
    //grid.setSelectionMode(Grid.SelectionMode.SINGLE).select(user);
    userRepository.save(user);

    // reload data from DB
    ListDataProvider<User> dataProvider = DataProvider.ofCollection(userRepository.findAll());
    grid.setDataProvider(dataProvider);

    // or in short form (it will do the same):
    // grid.setItems(userRepository.findAll());
}

Наконец я нашел присоску: grid.setItems(userRepository.findAll());

Java 24.06.2019 18:49

Большое спасибо за ваше предложение!

Java 24.06.2019 20:07

Итак, grid.setItems(userRepository.findAll()); — это краткая форма моего второго подхода. Значит ли это, что первый подход не сработал? Если это так, я отредактирую это из своего ответа.

kscherrer 25.06.2019 08:23

да, по некоторым причинам (например, я использую Vaadin 14) работает только с grid.setItems(userRepository.findAll()); Я улучшился до элегантного Refresh(); метод: private void refresh() { grid.setItems(userRepository.findAll()); }

Java 25.06.2019 12:42

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