Situation
I have a web application which uses JPA as a link to the underlying database. When the user modifies entities through the UI, these changes are not immediately saved to the database.
Question
How can I check if an Entity and the underlying database are out of sync (i.e. the Entity is dirty).
Furthermore, is it possible to be notified of this automatically, e.g. through a listener mechanism?
Is this possible using the JPA specification? I currently use Hibernate as underlying persistency manager, but a solution within the JPA (EntityManager) would be better.
If it is not possible using JPA, solutions using the Hibernate 4 persistency API are also welcome!
Purpose
I would like to use this to mark the UI representations of dirty objects as dirty.
Longer version
Upon loading the web UI, entities are loaded from the database. These entities may then be modified by the user in the UI. However, these changes are not immediately saved to the database.
To do this, the user must push the save button, which executes the following code in the persistency module:
// in data-persistency module
public class MyObjectManager {
...
public void saveMyObject(MyObjectEntity moe) {
...
EntityManager em = DatabaseJPAConnector.getEntityManager();
em.getTransaction().begin();
moe.saveOrUpdate(em); // persists or merges moe and all its childs
em.getTransaction().commit();
...
}
...
}
To test whether an object is out of sync I would like a method to verify if an Entity is currently dirty and/or an eventing mechanism to notify interested GUI elements automatically when the dirty state is changed:
// in data-persistency module
public class MyObjectManager {
...
public boolean isDirty(MyObjectEntity moe) {
...
EntityManager em = DatabaseJPAConnector.getEntityManager();
return ???
}
...
public void addDirtyListener(DirtyStateListener listener) {
// publisher-subscriber pattern
}
}
// in gui module
public class MyGUIComponent {
if (data.isDirty(moe)) {
// mark UI object as dirty
}
MyGUIComponent() {
data.addDirtyListener(new DirtyStateListener() {
public void dirtyStateChanged(DirtyStateEvent event) {
// update dirtyness state of UI object
}
}
}
}