春天JPA切换场:StaleObjectStateException

春天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()电话完成交易或其他事情之后,我需要做些什么?我从不故意打开事务(或者关闭自动提交,也许)。

+0

您确定您的AJAX调用正在处理一次处理程序方法吗?看起来你可能有两个线程争夺你的“文档”。 – millhouse

+0

就是这样。我使用jQuery的$()。live()方法绑定了change事件,并重新设置每次我重建页面的那一部分时,导致在同一元素上重复绑定。我会在答案中更详细地解释问题。 –

我想通了。它与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复选框仅在其更改事件中绑定一次,切换似乎完美无缺,每个人都很高兴。

+0

感谢帖子,对我来说,我将它移出一个函数,然后在需要的地方调用它 – Binaryrespawn