我正在使用Vaadin为单个数据库表构建一个简单的编辑器,使用JPAContainer和Vaadin Table组件。删除和编辑项目工作正常,但我在添加项目时遇到问题。
Vaadin教程解释了如何使用弹出窗口添加项目,但我想通过在表格中使用新的空行来添加项目。所需的功能是为用户提供一行默认数据,然后允许用户在对新行中的数据感到满意后保存数据。
我遇到的问题是,当我尝试做我认为应该工作的事情时,我得到UnsupportedOperation。
我的表已设置并绑定到位置实体的JPAContainer:
private JPAContainer locations = JPAContainerFactory.make(Location.class,PERSISTENCE_UNIT);
我将表设置为缓冲,因此在用户单击保存按钮之前,我不会将数据保存到数据库:
locationTable = new Table(null,locations);
locationTable.setVisibleColumns(new Object[]{ "id","x","y","z","createDate","lastModDate" } );
locationTable.setSelectable(true);
locationTable.setSizeFull();
locationTable.setImmediate(true);
locationTable.setBuffered(true);
locationTable.setVisible(true);
locationTable.setEditable(true);
..保存按钮保存对数据库的更改:
Button saveButton = new Button("Save Changes");
saveButton.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
locations.commit();
statusLabel.setCaption("Changes Saved");
}
});
然后我绑定了一个尝试添加新按钮的按钮。
Button addButton = new Button("Add An Item");
addButton.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
Object newkey = locationTable.addItem(new Object[]{"NEWLOCATION","0","0","0","7/10/2013","7/10/2013"}, "NEWLOCATION");
locationTable.select(newkey);
statusLabel.setCaption("Item Added. Populate Data and click Save to make permanent.");
}
});
单击additem按钮会抛出UnSupportedOperationException。
我试过调用addItem的其他变种,但我无法工作。有人知道如何通过在表中使用新行来在表中创建新项目吗?
完成init()源:
@Override
protected void init(VaadinRequest request) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
final Label statusLabel = new Label("");
locationTable = new Table(null,locations);
locationTable.setVisibleColumns(new Object[]{ "id","x","y","z","createDate","lastModDate" } );
locationTable.setSelectable(true);
locationTable.setSizeFull();
locationTable.setImmediate(true);
locationTable.setBuffered(true);
locationTable.setVisible(true);
locationTable.setEditable(true);
Button saveButton = new Button("Save Changes");
saveButton.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
locations.commit();
statusLabel.setCaption("Changes Saved");
}
});
Button addButton = new Button("Add An Item");
addButton.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
Object newkey = locationTable.addItem(new Object[]{"NEWLOCATION","0","0","0","7/10/2013","7/10/2013"}, "NEWLOCATION");
locationTable.select(newkey);
statusLabel.setCaption("Item Added. Populate Data and click Save to make permanent.");
}
});
Button deleteButton = new Button("Delete Selected");
deleteButton.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
locations.removeItem(locationTable.getValue());
statusLabel.setCaption("Item Removed. Click Save to make permanent.");
}
});
layout.addComponent(locationTable );
layout.addComponent(saveButton);
layout.addComponent(addButton);
layout.addComponent(deleteButton);
layout.addComponent(statusLabel);
}
答案 0 :(得分:0)
好的,由于Vaadin JPA容器的限制,可以执行我之后的操作,但仅限于具有自动生成主键的实体。 我使用自动生成的id按预期工作的代码,但如果不是这样,则会失败。
向容器添加新项时,com.vaadin.ui.Table委托给它的容器,在没有提供itemId的情况下调用.addItem(),或者在提供的情况下调用getItem()。 / p>
对于新项目,调用.addItem():
/**
* <strong>This functionality is not fully supported by this
* implementation.</strong> The implementation tries to call empty parameter
* constructor and add entity as such to database. If identifiers are not
* autogenerated or empty parameter constructor does not exist, the
* operation will fail and throw UnSupportedOperationException.
* <p>
* {@inheritDoc }
*/
public Object addItem() throws UnsupportedOperationException {
try {
T newInstance = getEntityClass().newInstance();
Object id = addEntity(newInstance);
return id;
} catch (InstantiationException e) {
} catch (IllegalAccessException e) {
}
throw new UnsupportedOperationException();
}
此代码解释了问题 - 如果无法在数据库中使用null contstructor创建实体,则会失败。
Vaadin示例通过使用Form对象来收集数据,然后在完全填充数据之后调用addEntity()方法。