@RequestMapping(value = "/document/togglevisible/{docId}")
public void toggleImageVisible(@PathVariable Integer docId) {
Document doc = Document.findDocument(docId);
if (doc.getVisible() == null) {
doc.setVisible(1);
} else {
doc.setVisible(null);
}
doc.merge();
}
当复选框值发生变化时,我正在使用ajax调用:
$.get('/document/togglevisible/' + $(this).attr('data'));
当我通过浏览器点击该URL时,它只是在我的数据库中切换字段,没有任何问题。
当我从这个ajax调用中点击它时,无论它是否存在都是不确定的。挖掘Firebug以查看实际响应,我看到Spring抛出这条消息:
org.hibernate.StaleObjectStateException: Row was updated or deleted by
another transaction (or unsaved-value mapping was incorrect)
从未听说过任何此类事情,谷歌也没多大帮助。在merge()
致电完成交易之后,我需要做些什么吗?我从来没有故意打开交易(或者可能关闭了自动提交)。
答案 0 :(得分:1)
我明白了。它与Spring JPA无关。
在javascript函数中,我填充了文档列表(带有复选框以触发这种可见性切换)我说:
if (window.Docs.length > 0) {
$('.mediaVisibilityToggle').live('change', function () {
$.get("/document/togglevisible/" + $(this).attr('data-rel'));
});
}
在那里看到.live
?这告诉jQuery绑定该事件并使其与所有DOM更改保持一致。因此,当我更改DOM并列出与不同父对象关联的文档时,我构建它们的布局并在该选择器类上调用live
AGAIN,从而导致两个绑定坐在那里。因此,每次按钮都会重新激活其ajax调用,因为我重新绘制了此部分页面。没有es bueno。
我把它改为:
$('.mediaVisibilityToggle').unbind('change');
window.Docs.each( function(item) {
// do my thing to clear that element and redraw my list of documents
});
if (window.Docs.length > 0) {
$('.mediaVisibilityToggle').bind('change', function () {
$.get("/mavenmanagement/admin/document/togglevisible/" + $(this).attr('data-rel'));
});
}
我可能只是将我的.live
号召唤到某个地方的全球一次性范围,但就我的事件而言,这感觉就像是一种更好的方法来控制什么是什么。所以现在每个.mediaVisibilityToggle
复选框在其更改事件上只绑定一次,切换似乎完美无缺,并且每个人都很开心。