简单Java SE更新代码中的OptimisticLockException

时间:2015-09-07 10:39:47

标签: java jpa

我遇到了一个我不知道如何解决的问题(和往常一样,这可能是我身边的一个愚蠢的错误)。我正在使用Embedded Derby和JPA(EclipseLink)编写Java SE Swing应用程序。没有多用户,虽然我可以打开几个tabbedpanes来执行不同的操作。但是,在这个问题中,我使用单个窗格来重现问题。

在该测试面板中,每当我将其添加为选项卡式窗格时,我都会运行以下代码:

public void onTabPanelAdded() {
    if (entityManager == null) {
        // emf is a static property in the Main class
        // so I just create one EntityManagerFactory,
        // but one EntityManager for each JPanel
        entityManager = emf.createEntityManager();
    }

    selectedL10n = entityManager.find(L10n.class, 1);
    l10nCodeField.setText(selectedL10n.getCode());
    descripField.setText(selectedL10n.getName());
    l10nCodeField.requestFocusInWindow();
}

每当我关闭选项卡式窗格(隐藏JPanel)时,我都会运行以下代码:

public void onTabPanelRemoved() {
    if (entityManager.getTransaction().isActive()) {
        entityManager.flush();
        entityManager.getTransaction().commit();
    }
    entityManager.close();
    entityManager = null;
}

虽然在关闭/隐藏JPanel之前发生了错误(只是为了让你不再认为它与不释放EntityManager有关)。

现在,正如您在第一个代码块中看到的那样,测试面板从数据库中检索持久化实体并填充面板中的TextFields。在对数据进行简单更改并单击我输入的“保存”按钮后,运行以下代码:

private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {
    entityManager.getTransaction().begin();
    selectedL10n = entityManager.merge(selectedL10n);
    selectedL10n.setCode(l10nCodeField.getText());
    selectedL10n.setName(descripField.getText());
    try {
        entityManager.getTransaction().commit();
    } catch (Exception ex) {
        Logger.getLogger(L10nGUIManager.class.getName()).log(
            Level.SEVERE, null, ex);
    }
}

如您所见,我打开事务,合并实体以确保它被管理(我通过使用entityManager.contains(selectedL10n)对此进行了双重检查),应用更改并提交。然而,尽管没有应用程序的其他部分且没有其他实例/用户正在使用它,但我得到了一个OptimisticLockException。我根本就不明白。

该实体具有带注释的版本字段:

@Entity
public class L10n implements Serializable, Comparable<L10n> {
@Version
private int entityVersion;
...

与他相应的getter / setter。我完全迷失了原因。

TIA

0 个答案:

没有答案