延迟加载的 primefaces 数据表在 SQL 语句完成执行之前更新
当 primefaces 数据表在用于更新\从该表中删除实体的 SQL 语句完成执行之前更新时,我遇到了问题。
01:08:13,255 INFO [reg.data.model.LazyEventDataModelMod] - Loading the lazy event data between 0 and 10
01:08:13,256 DEBUG [org.hibernate.SQL] -
select
count(*) as col_0_0_
from
events event0_ limit ?
01:08:13,394 DEBUG [org.hibernate.SQL] -
delete
from
events
where
id=?
问题是实体管理器不会返回任何内容来表明它已成功执行删除\更新查询。
我使用 JSF 2、Weld 1.1.5.Final、Primefaces 3.0.1、Seam 持久性/事务/焊接 3.0.1.Final。
服务器是 Tomcat 7。
以下是调用控制器 bean 上的操作的按钮的代码:
<p:commandButton id="deleteButton" value="#{msg.delete}"
icon="ui-icon-trash" update=":events_form :messages"
actionListener="#{eventController.delete()}" />
<p:commandButton id="refreshButton" value="#{msg.refresh}"
icon="ui-icon-refresh" update=":events_form :messages" />
按下第一个按钮后不会发生更新,但第二个按钮会更新表,它们都有相同的 ajax更新部分。
delete()方法的代码:
public void delete() {
if (getSelEvent() != null) {
log.debug("deleting event " + getSelEvent().getId());
dao.delete(getSelEvent());
// Tried putting the code for reloading te data model here, but it is also executed before the sql statements...
} else {
log.warn("delete action cannot proceed, no event selected!");
}
}
dao中的deleteById()方法:
public void delete(T entity) {
if (em == null)
init();
log.debugf("removing %s instance", simpleName);
entity = em.merge(entity);
// The problem lies here - em.remove() does not return any value to indicate success/failure, so the control is released before the SQL statements finish execution
em.remove(entity);
}
数据表:
<p:dataTable id="event_list" value="#{eventController.lazyModel}"
var="event" rowKey="#{event.id}" paginator="true" rows="20"
selection="#{eventController.selEvent}" selectionMode="single"
onRowSelectUpdate="content,messages"
onRowEditUpdate="content,messages"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,25,50,100">
LazyDataModel类:
public class LazyEventDataModel extends LazyDataModel<Event> {
private static final long serialVersionUID = 2386224274507659474L;
private EventDAO dao;
private Logger log = Logger.getLogger(LazyEventDataModel.class);
private List<Event> data;
public LazyEventDataModel() {
dao = new EventDAO();
}
@Override
public Event getRowData(String rowKey) {
return dao.find(Long.parseLong(rowKey));
}
@Override
public Object getRowKey(Event event) {
return event.getId();
}
@Override
public List<Event> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, String> filters) {
if (sortField == null || "".equals(sortField)) {
sortField = "event_date";
sortOrder = SortOrder.DESCENDING;
}
if (sortField.equals("date"))
sortField = "event_date";
// Get the paginated and sorted data
data = dao.findPageObjects(Event.class, first, pageSize, sortField,
sortOrder, filters);
log.infof("Loading the lazy event data between " + first + " and "
+ (first + pageSize));
// Set the row count
this.setRowCount(Global.safeLongToInt(dao.count()));
return data;
}
}
我现在能想到的唯一解决方案是在调用dao.delete(getSelEvent())并刷新后添加计时器该计时器之后的数据模型。
I have a problem when the primefaces data table gets updated before the SQL statements for updating\removing entities from this table finish executing.
01:08:13,255 INFO [reg.data.model.LazyEventDataModelMod] - Loading the lazy event data between 0 and 10
01:08:13,256 DEBUG [org.hibernate.SQL] -
select
count(*) as col_0_0_
from
events event0_ limit ?
01:08:13,394 DEBUG [org.hibernate.SQL] -
delete
from
events
where
id=?
The problem is that the entity manager doesn't return anything to indicate that it had successfully executed the delete\update query.
I use JSF 2, Weld 1.1.5.Final, Primefaces 3.0.1, Seam persistence/transaction/solder 3.0.1.Final.
The server is Tomcat 7.
Here is the code for the button that invokes the action on the controller bean:
<p:commandButton id="deleteButton" value="#{msg.delete}"
icon="ui-icon-trash" update=":events_form :messages"
actionListener="#{eventController.delete()}" />
<p:commandButton id="refreshButton" value="#{msg.refresh}"
icon="ui-icon-refresh" update=":events_form :messages" />
The update doesn't happen after the first button is pressed, however the second one does update the table, both of them have identical ajax update sections.
Code of the delete() method:
public void delete() {
if (getSelEvent() != null) {
log.debug("deleting event " + getSelEvent().getId());
dao.delete(getSelEvent());
// Tried putting the code for reloading te data model here, but it is also executed before the sql statements...
} else {
log.warn("delete action cannot proceed, no event selected!");
}
}
deleteById() method in the dao:
public void delete(T entity) {
if (em == null)
init();
log.debugf("removing %s instance", simpleName);
entity = em.merge(entity);
// The problem lies here - em.remove() does not return any value to indicate success/failure, so the control is released before the SQL statements finish execution
em.remove(entity);
}
data table:
<p:dataTable id="event_list" value="#{eventController.lazyModel}"
var="event" rowKey="#{event.id}" paginator="true" rows="20"
selection="#{eventController.selEvent}" selectionMode="single"
onRowSelectUpdate="content,messages"
onRowEditUpdate="content,messages"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,25,50,100">
LazyDataModel class:
public class LazyEventDataModel extends LazyDataModel<Event> {
private static final long serialVersionUID = 2386224274507659474L;
private EventDAO dao;
private Logger log = Logger.getLogger(LazyEventDataModel.class);
private List<Event> data;
public LazyEventDataModel() {
dao = new EventDAO();
}
@Override
public Event getRowData(String rowKey) {
return dao.find(Long.parseLong(rowKey));
}
@Override
public Object getRowKey(Event event) {
return event.getId();
}
@Override
public List<Event> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, String> filters) {
if (sortField == null || "".equals(sortField)) {
sortField = "event_date";
sortOrder = SortOrder.DESCENDING;
}
if (sortField.equals("date"))
sortField = "event_date";
// Get the paginated and sorted data
data = dao.findPageObjects(Event.class, first, pageSize, sortField,
sortOrder, filters);
log.infof("Loading the lazy event data between " + first + " and "
+ (first + pageSize));
// Set the row count
this.setRowCount(Global.safeLongToInt(dao.count()));
return data;
}
}
The only solution I can think of right now would be adding the timer after calling the dao.delete(getSelEvent()) and refreshing the data model after that timer.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
命令按钮的更新属性也必须包含数据表。一旦 ajax 调用完成,更新中设置的任何内容都会发生。考虑到您没有创建单独的线程来执行数据库操作(这将使 ajax 请求几乎立即完成),请执行以下操作。
但需要注意的是:由于某种原因,在更新属性中引用数据表的 id 不起作用。我通常只是用 panelGroup 包裹它并告诉按钮更新 panelGroup。像这样的事情:
请注意,primeFaces 按钮组件默认使用 ajax,因此您根本不需要 jsf2 ajax 标签。
The update attribute of your commandButton must include the datatable as well. Whatever is set in the update will happen once the ajax call is completed. Considering that you're not creating a separate thread to perform the database operations (which would make the ajax request finish almost instantly), do as follows.
One caveat, though: for some reason referencing the id of the datatable in the update attribute does not work. I normally just wrap it with a panelGroup and tell the button to update the panelGroup instead. Something like this:
Note that the primeFaces button components use ajax by default, so you don't need the jsf2 ajax tag at all.