Я ищу пример 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());
}




Ваш способ кажется жизнеспособным, но у вас есть другая проблема.
Вы получаете ObjectOptimisticLockingFailureException, что означает, что ваш объект User уже был изменен в базе данных.
Вы должны перезагрузить объект из базы данных перед установкой флага anwesend.
я рад помочь
Я согласен с ответом Саймона Мартинелли. Ваши данные устарели (не обновлены) и требуют перезагрузки.
Вот как вы могли бы это сделать.
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());
Большое спасибо за ваше предложение!
Итак, grid.setItems(userRepository.findAll()); — это краткая форма моего второго подхода. Значит ли это, что первый подход не сработал? Если это так, я отредактирую это из своего ответа.
да, по некоторым причинам (например, я использую Vaadin 14) работает только с grid.setItems(userRepository.findAll()); Я улучшился до элегантного Refresh(); метод: private void refresh() { grid.setItems(userRepository.findAll()); }
ИМХО это неправильный подход. Упомянутая вами проблема, скорее всего, столкнется с вами только во второй раз, когда вы переключите bool на пользователя? Итак, теперь вы исправили свое сохранение на устаревшем объекте для следующего раза, если неизменный объект не будет изменен другим пользователем. Я думаю, вам следует перезагрузить пользователя в начале
changeIsAnwesendи убедиться, что «переключение» является намерением пользователя (а не просто отрицанием значения из последней увиденной сетки). Затем перезагрузите сетку и т. д., как у вас.