将 Vaadin CheckBox 保存到 JPA 的正确方法是什么?
What is the correct way to save a Vaadin CheckBox to 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 之前,我问在 Vaadin 中将 Checkbox 保存到 JPA 的正确和常用方法是什么。
非常感谢!
已解决:
感谢@Kaspar Scherrer 和@Simon Martinelli 的建议
我把方法参数改成(User user,Grid grid)
并在 userRepository.save(user);
之后添加
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
,这意味着同时你的用户对象已经在数据库中被更改。
您必须在设置 anwesend 标志之前从数据库重新加载实体。
我同意 Simon Martinelli 的回答。您的数据 "stale"(不是最新的),需要重新加载。
以下是您的操作方法。
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());
}
我正在寻找一个 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 之前,我问在 Vaadin 中将 Checkbox 保存到 JPA 的正确和常用方法是什么。
非常感谢!
已解决:
感谢@Kaspar Scherrer 和@Simon Martinelli 的建议
我把方法参数改成(User user,Grid grid) 并在 userRepository.save(user);
之后添加 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
,这意味着同时你的用户对象已经在数据库中被更改。
您必须在设置 anwesend 标志之前从数据库重新加载实体。
我同意 Simon Martinelli 的回答。您的数据 "stale"(不是最新的),需要重新加载。
以下是您的操作方法。
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());
}