春天JPA切换场:StaleObjectStateException
@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调用,当一个复选框值变化:春天JPA切换场:StaleObjectStateException
$.get('/document/togglevisible/' + $(this).attr('data'));
当我打的URL通过浏览器,按下该键则在我的数据库领域只是出色,没有问题。
当我从这个Ajax调用它时,它是否可以。挖掘到萤火虫来看看实际的响应,我看到了春天扔了此消息:
org.hibernate.StaleObjectStateException: Row was updated or deleted by
another transaction (or unsaved-value mapping was incorrect)
从来没有听说有这样的事情,和谷歌的没有太大的帮助。在我的merge()
电话完成交易或其他事情之后,我需要做些什么?我从不故意打开事务(或者关闭自动提交,也许)。
我想通了。它与Spring JPA无关。
在javascript函数,我填充的文件列表(与他们的复选框火的可见性行为这种切换)我说:
if (window.Docs.length > 0) {
$('.mediaVisibilityToggle').live('change', function() {
$.get("/document/togglevisible/" + $(this).attr('data-rel'));
});
}
请参阅.live
呢?这告诉jQuery绑定该事件,并在所有DOM更改中保持绑定。因此,当我改变DOM并列出与不同父对象关联的文档时,我构建了它们的布局并在该选择器类上再次调用live
,从而导致出现两个绑定。所以每个按钮都会重复触发它的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
复选框仅在其更改事件中绑定一次,切换似乎完美无缺,每个人都很高兴。
感谢帖子,对我来说,我将它移出一个函数,然后在需要的地方调用它 – Binaryrespawn
您确定您的AJAX调用正在处理一次处理程序方法吗?看起来你可能有两个线程争夺你的“文档”。 – millhouse
就是这样。我使用jQuery的$()。live()方法绑定了change事件,并重新设置每次我重建页面的那一部分时,导致在同一元素上重复绑定。我会在答案中更详细地解释问题。 –