简单Java SE更新代码中的OptimisticLockException
我遇到了一个我不知道如何解决的问题(和往常一样,这可能是我这边的一个愚蠢的错误)。我正在使用嵌入式Derby和JPA(EclipseLink)编写一个JavaSE Swing应用程序。没有多用户,尽管我可以打开几个选项卡窗格来执行不同的操作。然而,在这个问题中,我使用一个窗格来重现这个问题 在该测试面板中,每当我将其添加为选项卡式窗格时,我都会运行以下代码:简单Java SE更新代码中的OptimisticLockException,java,jpa,Java,Jpa,我遇到了一个我不知道如何解决的问题(和往常一样,这可能是我这边的一个愚蠢的错误)。我正在使用嵌入式Derby和JPA(EclipseLink)编写一个JavaSE Swing应用程序。没有多用户,尽管我可以打开几个选项卡窗格来执行不同的操作。然而,在这个问题中,我使用一个窗格来重现这个问题 在该测试面板中,每当我将其添加为选项卡式窗格时,我都会运行以下代码: public void onTabPanelAdded() { if (entityManager == null) {
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();
}
public void onTabPanelRemoved() {
if (entityManager.getTransaction().isActive()) {
entityManager.flush();
entityManager.getTransaction().commit();
}
entityManager.close();
entityManager = null;
}
每当我关闭选项卡式窗格(隐藏JPanel)时,我都会运行以下代码:
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();
}
public void onTabPanelRemoved() {
if (entityManager.getTransaction().isActive()) {
entityManager.flush();
entityManager.getTransaction().commit();
}
entityManager.close();
entityManager = null;
}
尽管错误发生在关闭/隐藏JPanel之前(只是为了让您不再认为它与不释放EntityManager有关)
现在,正如您在第一段代码中看到的,测试面板从DB中检索一个持久化实体,并填充面板中的文本字段。在对数据进行简单更改并单击我放入的保存按钮后,将运行以下代码:
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;
...
@实体
公共类L10n实现了可序列化、可比较的{
@版本
私有int实体版本;
...
我完全不知道为什么
TIA不是专家,所以发布评论-我看到
flush
是将持久性上下文同步到基础数据库。而commit
是提交当前资源事务,将任何未刷新的更改写入数据库。-我怀疑您不想同时执行这两项操作,或者如果执行,则应使用commit
thenflush
。谢谢,OldCurmudgeon。我没有在这段代码中使用flush(),也没有在我的应用程序中普遍使用它。我希望这不是导致此错误的原因,否则我将不得不查看所有应用程序。:-)我没有使用flush()在这段代码中-呃…是的,您已经删除了-ontabpanel…entityManager.flush()
Oops…是的,你是对的。但是错误发生在执行onTabPanelRemoved之前,正如我所说。onTabPanelRemoved代码的存在只是为了表明错误不是由于在删除/读取选项卡窗格时打开EntityManager并尝试创建一个新的冲突造成的。