Spring JPA切换字段超过AJAX错误:StaleObjectStateException

时间:2011-11-16 21:03:06

标签: hibernate jpa spring-mvc spring-roo

@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()致电完成交易之后,我需要做些什么吗?我从来没有故意打开交易(或者可能关闭了自动提交)。

1 个答案:

答案 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复选框在其更改事件上只绑定一次,切换似乎完美无缺,并且每个人都很开心。