• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

JPA Refresh Query from EJB3 In Action

 
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,

I'm reading "EJB3 In Action" and am on page 304.
In the book, the authors are writing an ItemManagerBean to show how JPA operations work.
One of their methods is for refreshing the Entity back to the way it is in the DB - "allow the user to start over with modifying a listing (think of an HTTP form's "reset" button)".



My question is why the merge operation was necessary? As I understand it, refresh() will bring an Entity into the Persistence Context, and their diagram on page 298 would back this up. So as I see it, the merge is unnecessary. The errata doesn't list this as a mistake, so am I misunderstanding something here?

Thanks,

MG
 
Sheriff
Posts: 14691
16
Eclipse IDE VI Editor Ubuntu
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
As far as I remember, merge() is used to put a detached or new entity in the persistence context. refresh() needs needs a managed entity, so if the entity is detached or new, it will fail. To prevent this, merge() is being used before calling refresh().
 
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
To clarify Cristophe's response, here's my take on the workflow:

1. merge(item) will take the detached 'item' and make it managed by retrieving the corresponding Item values from the database (assuming, of course, that it exists in the database); however, merge() takes any changed values from 'item' and overwrites the values retrieved from the database
2. to fix this, refresh() is called which reverts the changed values to their original database values

Result: the changes to 'item' have been undone
 
Mark Garland
Ranch Hand
Posts: 226
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Christophe and Peter,

Thank you both for your responses - much appreciated. I've not been ignoring this thread, just leaving it to gather responses whilst I study other areas.

I've just been re-covering this section (and writing a test/learning app) and now see why the merge is necessary (it turns the Entity into a managed one). It's like the opposite of detach. It's a shame that the changes you don't want have to be written to the persistence context (by the merge) and then have to be written back over (by the refresh), but I understand why it's happening.
I've come to the conclusion (difficult if you can't see the book, but useful if authors are reading) that the diagram on p298 is confusing. It shows an entity going from a detached to a managed state and is listed with the operations "merge()/refresh()". This implies that refresh results in a managed Entity, which we know not to be true. The slash also doesn't mean that these operations must be sequential as other parts of the diagram use the slash as the normal 'either/or' operator.


So, I have been looking at: http://download.oracle.com/javaee/6/api/javax/persistence/EntityManager.html and at the basic operations to see how this works. Feel free to correct me if any of the below is wrong - going through it has been a useful revision exercise.

Persist - makes an Entity managed. To invoke this, my Entity must not be managed, or I risk getting a EntityExistsException.
Merge - returns a managed Entity. It doesn't say that it'll throw an exception if the Entity is already managed, although the call wouldn't make much sense.
Refresh - (topic of this thread). Throws an IllegalArgumentException if "the entity is not managed". So, we'd need to make it managed somehow and so merge could be used.
Remove - Throws an IllegalArgumentException if the Entity "is a detached entity". Same as merge.

Thanks again,

MG
 
Peter Gough
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Your assessment is correct. You may want to reference the EJB JPA Spec; it's a bit of a read, but has real good info in it.
From the spec:

The state of a managed entity instance is refreshed from the database by invoking the refresh method
on it or by cascading the refresh operation.


This is quite useful when using long transactions, handling changes to cascaded children and in locking scenarios.
Example (not verified for correctness, only here to show a generalized example -- there are many (better) ways to do locking):

 
Don't get me started about those stupid light bulbs.
reply
    Bookmark Topic Watch Topic
  • New Topic