users@jpa-spec.java.net

[jpa-spec users] Re: Enhancement: EntityManager.find() method that takes an ID and a version?

From: Kevin Sutter <sutter_at_us.ibm.com>
Date: Thu, 26 Jun 2014 11:20:02 -0500

Thanks, Laird,

I think your second "goal" hits the issue on the head:
> 2. Except in the case of DIY merges, I don't think there's another
> case in all of JPA where you have to do something with the version
> yourself as a programmer.

This is specific to DIY merges. All of the rest of the version processing
is hidden from the user, but in the case of DIY merging, users are now
required to understand how to access and process the version columns. Now
I understand what you were driving at. I do like the idea of maybe
enhancing the getReference() instead of the find(). And, since the
EntityNotFoundException already exists on the getReference, I would
propose that we stick with that vs the check for null.

In any case, I can see the benefit of this idea, now we just need Linda to
pipe in... :-)

----------------------------------------------------------------------------------------------------------------------------------------------------------------
Kevin Sutter
STSM, Java EE and Java Persistence API (JPA) architect
mail: sutter_at_us.ibm.com, Kevin Sutter/Rochester/IBM
http://webspherepersistence.blogspot.com/
phone: tl-553-3620 (office), 507-253-3620 (office)
http://openjpa.apache.org/
 

Laird Nelson <ljnelson_at_gmail.com> wrote on 06/19/2014 11:42:14 AM:

> From: Laird Nelson <ljnelson_at_gmail.com>
> To: users_at_jpa-spec.java.net
> Date: 06/19/2014 11:45 AM
> Subject: [jpa-spec users] Re: Enhancement: EntityManager.find()
> method that takes an ID and a version?
>
> On Thu, Jun 19, 2014 at 8:26 AM, Kevin Sutter <sutter_at_us.ibm.com> wrote:
> Hi Laird,
> Your write-up and the referenced SO post were helpful in
> understanding the dilemma of JPA merge and the DIY approach.
> Unfortunately, I couldn't make the leap to your proposal:
>
> > Would it make sense to add a find() variant that takes both an ID
> > and a version and throws an OptimisticLockException if a persistent
> > entity with those coordinates does not exist? Or am I missing
> > something more fundamental somewhere in the API that would explain
> > why this is not needed?

> Specific to your request, how is this proposal different from just
> doing the normal find() operation with the ID and then just
> comparing the version that is returned with the version you are
> interested in? As your previous paragraph suggested... This
> approach avoids the exception processing overhead as well, which I
> am not in favor of. You are just trying to move this version
> compare logic from the user to the JPA provider? Hmmm... Just not
> seeing the advantage here.
>
> That's all fair, I suppose (although I'm not understanding the
> exception processing overhead? wouldn't the find() call just return
> null? or do you mean the OptimisticLockException which you throw
> yourself in DIY merges today?); what I really should have written
> was I'd like a getReference() variant that takes an ID and a
> version. Does that make more sense? Then a state fetch wouldn't
> have to happen at all.
>
> To spell it out:
>
> final Person p = em.getReference(Person.class, 32 /* ID */, 3 /* version
*/);
> if (p != null) { // if you're not into exceptions :-)
> // if we get here we're good; no intervening edits have happened
> // if we DON'T get here, it's because there's been a concurrency issue
> // note as well that p's state has not been fetched (apart from
> his PK and version)
> p.setLastName("Nelson"); // begin DIY merging
> // this should just result in an UPDATE PERSON SET LASTNAME = 'Nelson'
> // no additional SELECTs
> }
>
> From a philosophical perspective, I guess there are a couple things in
play:
> 1. An entity's "coordinates" really are the combination of its
> primary key and its version (if it has one, of course). It seems
> like that should be reflected in the API somewhere somehow. Even
> when you do a simple find() call, you're implicitly adding, "...if
> it's the latest version, of course" to the semantics of the query.
> 2. Except in the case of DIY merges, I don't think there's another
> case in all of JPA where you have to do something with the version
> yourself as a programmer. It is a field that is managed by the JPA
> provider, updates to it are forbidden, it is only useful for
> comparing for equality, etc. I'm not claiming anything hard or
> technical here; just that it "feels wrong" to have to reach into an
> entity, grab this immutable, opaque, provider-managed thing and
> compare it against the immutable, opaque, provider-managed thing
> that was previously handed to you at some point...feels like the
> wrong actor is being made to perform these tasks just so he doesn't
> shoot his own leg off.
> Best,
> Laird
>
> --
> http://about.me/lairdnelson