openjpa-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <cefn.ho...@bt.com>
Subject Simple object synchronization
Date Mon, 22 Nov 2010 13:02:58 GMT
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
Mime
View raw message