Buscar
Social
Ofertas laborales ES

Foro sobre Java EE > OptimisticLockException en código sencillo de Java SE

Ya sé que este es un foro de Java EE y el título suena a despiste claro, pero es que el problema es con JPA. :-)

Estoy escribiendo una aplicación Java SE Swing con Derby Embedded y JPA (EclipseLink). No es multiusuario, aunque se pueden abrir varias pestañas para realizar distintas operaciones. No obstante, en este problema uso una sola pestaña para reproducirlo.

En el panel que he hecho para la prueba, siempre que lo añado al JTabbedPane, ejecuto este código:


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();
}

Y al cerrar la pestaña (ocultar el JPanel) este otro código:


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

aunque el error sucede antes de cerrar/ocultar el panel (lo pongo solo para que no creáis que hay un problema con EntityManager duplicados o algo así)·

Ahora bien, el panel de prueba, como se ve en el primer bloque de código, recupera una entidad persistida de la base de datos y rellena unos campos en el panel para que los pueda modificar. Tras hacer algún cambio en ellos y pulsar el botón Save, se ejecuta este código, que es donde falla:


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);
}
}

Como puede verse, abro la transacción, fusiono la entidad para asegurarme de que está manejada por el EntityManager (y lo he comprobado usando entityManager.contains(selectedL10n) y viendo que devuelve true), aplico los cambios y hago commit. Y, a pesar de que no hay ninguna otra parte de la aplicación ni otras instancias o usuarios utilizando la tabla, me aparece una excepción OptimisticLockException. La verdad, no lo entiendo.

La entidad tiene un campo de versionado anotado:


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

con su getter/setter correspondiente. Estoy absolutamente perdido. Pregunté hace un par de días en StackOverflow y no he recibido ninguna respuesta útil. ¿Se os ocurre qué se me puede estar escapando? Incluso, ¿diríais que, a simple vista, el código está bien y no debería fallar?

Gracias por anticipado.

septiembre 8, 2015 | Registered Commenterrickiees