In my test app, I'm dealing with objects which didn't arise in a Persistence Context, but may need to be 'synchronized' with the corresponding stored data record. Can anyone point me to the right strategy for this very simple operation? My problem: I don't see a simple signature within the JPA APIs which takes account of this situation, and attempts to use promising ones are triggering errors.
Ideally I want to be able to say 'write this object's fields into the database, using its identity to determine which record to create or update. If it already exists then overwrite values, cascading changes to referenced objects as overwrites too. I must be missing something about the way these operations should be used given the error I'm seeing. In the app, filesystem traversals (which generate filesystem, folder and file objects using constructors) are repeated periodically, new items should be stored in new records, and existing items should have their records overwritten to incorporate any changes in the filesystem (reflected by the objects and their fields). >From looking at the OpenJPA DAO lifecycle, all the EntityManager operations >seem to assume your object originated with an EntityManager at some point in >the past, even if perhaps it has been detached since. Something which has been >independently originated using a constructor, but for which a corresponding >identity already exists doesn't seem to be anticipated, at least in the >descriptions provided. The App class in this github folder contains the problem merge(...) call... https://github.com/cefn/Spring-JPA-MVC-Postgres/tree/709f8be07e91b9b8a1b9dfa4443c2a09d22dc787/src/com/cefn/filesystem Currently the engine sees duplicate identities as a clash when using merge(), rather than an opportunity to synchronise the new object into the corresponding data record. I'd expect identity clashes to arise using persist() but not merge(). Calling either merge() or persist() on a FileImpl created using a constructor in a Filesystem traversal triggers the same error... org.apache.openjpa.lib.jdbc.ReportingSQLException: ERROR: duplicate key value violates unique constraint "file_pkey" {prepstmnt 32879825 INSERT INTO file (locationString, location, version, folder) VALUES (?, ?, ?, ?) [params=?, ?, ?, ?]} [code=0, state=23505] Of course it's possible for me to hard code a 'does this object already exist yet' sort of behaviour, using find(...), then delete, then persist, or alternatively comparing all the fields and changing them, but this obviously takes away from the advantage of annotation-oriented data objects. Assumptions about Data Object identity and fields will end up bleeding out into my application code where it should be handled by JPA conventions in the data objects. If I was to manually verify whether an object already exists, I'd want to say find(object) not find(identity). Otherwise I have to re-represent all the object->identity relationships which JPA has baked in. Once I've retrieved the record I'd presumably have to delete it (possibly causing a cascade of removes), and reinsert possibly the same data, which just seems wrong, but let me know if this is my only option. Given JPA is supposed to understand what identity and fields my object has, why can't I ask it to commit the new data into the database? I'd really benefit from suggestions how this should properly be approached. Cefn http://cefn.com