permaculture playing cards*
The moose likes EJB Certification (SCBCD/OCPJBCD) and the fly likes JPA Refresh Query from EJB3 In Action Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » EJB Certification (SCBCD/OCPJBCD)
Bookmark "JPA Refresh Query from EJB3 In Action" Watch "JPA Refresh Query from EJB3 In Action" New topic
Author

JPA Refresh Query from EJB3 In Action

Mark Garland
Ranch Hand

Joined: Nov 11, 2006
Posts: 226
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


28/06/06 - SCJP - 69%, 05/06/07 - SCWCD - 92%, 28/02/08 - IBM DB2 v9 Fundamentals (Exam 730) - 87%, 18/11/08 - IBM DB2 v9 DBA (Exam 731) - 89%, 26/02/11 - SCBCD - 88%
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14687
    
  16

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().


[My Blog]
All roads lead to JavaRanch
Peter Gough
Greenhorn

Joined: Sep 16, 2009
Posts: 9
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

Joined: Nov 11, 2006
Posts: 226
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

Joined: Sep 16, 2009
Posts: 9
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):

 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JPA Refresh Query from EJB3 In Action
 
Similar Threads
Help Ejb 3 In Action page 304
EJB3 in Action errata for EntityManager.refresh() method
a question regarding chap 9 ejb3 in action
Entitymanager.refresh doubt
EJB 3 IN ACTION - EntityManager merge() and refresh() method conflict