Как правильно сохранить Vaadin CheckBox в JPA? - PullRequest
0 голосов
/ 24 июня 2019

Я ищу, чтобы найти пример 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, я спрашиваюКакой правильный и обычный способ сохранить флажок в JPA в Vaadin.

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

РАЗРЕШЕНО:

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

Я изменяю параметры метода на (Пользователь, Сетка) и добавляю после 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());
}

Ответы [ 2 ]

1 голос
/ 24 июня 2019

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

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());
}
1 голос
/ 24 июня 2019

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

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

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

...