jaron.schut (18) [Avatar] Offline
#1
Hello,

On pages 298, 299 and 300 the methods of the EntityManager interface are discussed. In these pages the method refresh() is described as a method that can be used to reattach detached entities. I believe this to be wholly incorrect. According to the Java EE 5 API the refresh() method throws an IllegalArgumentException if passed a non-managed entity. In the first page refresh() is in the diagram shown to be a method resulting in a state transition of the entity. However the code example later in the book on page 304 correctly uses refresh() and merge() together to first merge the entity and then refreshing the returned reference.

Kind regards,

Jaron Schut
reza_rahman (456) [Avatar] Offline
#2
Re: Possible errata in chapter 9
You are correct. This was a late change in the life-cycle of the EJB 3.0 spec that we never went back and fixed...

Thanks,
Reza
dpanda (136) [Avatar] Offline
#3
Re: Possible errata in chapter 9
I don't know how we left this one. All our digrams and table shows the right info.

I got the incorrect statement: "The merge and refresh methods are intended for entities that have been retrieved from the database and are in the detached state."

I will update this in errata and will fix in the next print

regards
debu
PeterBStein (2) [Avatar] Offline
#4
Re: Possible errata in chapter 9
I have no EJB experienced, but am confused with:

"... on page 304 correctly uses refresh() and merge() together to first merge the entity and then refreshing the returned reference."

The example explains further on page 332 but I won't repeat it here.

I would think the purpose of method "undoItemChanges" is to restore the original values. How is this accomplished by calling merge(item) before refresh(item)? Won't the merge just update the database record? How is this like an "undo"?.

I do understand that the merge is done because "the refresh method only works on managed entities".

Please clarify.

Thanks,
Peter Stein
reza_rahman (456) [Avatar] Offline
#5
Re: Possible errata in chapter 9
Peter:

The "missing link" here is the fact that no database update actually takes place until the EntityManager is flushed at the end of the EJB transaction (when the method returns). The refresh operation, on the other hand, actually goes out and gets the database values as soon as the request is made. Makes sense? In other words, merge != database update, merge == manage the entity. On the other hand, refresh == database retrieval.

Cheers,
Reza
PeterBStein (2) [Avatar] Offline
#6
Re: Possible errata in chapter 9
Reza,

After reading your post, I went back and reread chapter 9. It's much clearer now.

My sincerest thanks,
Peter
reza_rahman (456) [Avatar] Offline
#7
Re: Possible errata in chapter 9
Peter:

No problems and you are very welcome. We'll try to clarify this better in the second edition, so thanks for pointing it out.

Cheers,
Reza
rsivan (11) [Avatar] Offline
#8
Re: Possible errata in chapter 9
Reza, I wasn't sure whether to reopen this old thread or start a new one.
The point is, I am myself confuse by the merge followed by refresh.
In particular, the updateItem method on page 303 in the second print uses entityManager.merge(item), which reinforces the feeling that merge is a transfer from the memory image at 'item' to the persistence layer, in addition to causing the bean to become managed.

I should have thought that just find(item.getId()) or something like that was the equivalent to an undo operation? (I am not experienced in EJB...)

I do appreciate your explanation on this thread but I still have trouble fully comprehending it.

Thanks.

PS Great book, I am enjoying it a lot
reza_rahman (456) [Avatar] Offline
#9
Re: Possible errata in chapter 9
Reuben,

Firstly, thanks for the kind words on the book. We tried to do our best while meeting the publisher's expectations around time-to-market (which has proven to be a complete non-issue). As you see however, we did miss some things although I'm told our book has less technical errors than some of our leading competitors. If you can, please do consider feedback on Amazon.com or elsewhere. It really helps us out.

OK, now that I did my "sales spiel", let's get down to business smilie. The entity manager is a little bit of a mind-shift if you are coming from a regular JDBC background (like me). The shift in thinking is twofold:

1. The entity manager is essentially a object repository/database for the session/transaction.
2. It is backed by a "real" database, but synchronization between the two happens only as required, not necessarily instantaneously. As a rough rule of thumb, synchronization happens at the end of a transaction or if you manually call flush. The practical reason for this is optimization (batch synchronizing once a set of changes are done).

Keeping this shift in paradigm in mind, let's revisit the merge+refresh. Remember that the entity is initially detached (JPA doesn't know about it). To attach it, we must call merge (refresh only works for entities that have been otherwise attached). This results in the entity state becoming "alive" in the entity manager. Here is the tricky part-remember that the database synchronization hasn't happened yet, so the database still contains the original state of the entity. When we now call refresh, the entity manager is forced to look-up the original values in the database and reset the values in the entity. At the end of the transaction, the entity manager does nothing (no synchronization is really necessary) and the entity changes are undone.

Does it make more sense now? It is indeed true that just doing a find and replacing the object reference would have accomplished the same thing. The point is that we wanted to show how refresh works smilie. Don't worry if this is a little confusing. The refresh operation, unlike the rest, is a little mind-bending. In truth, I'm, not sure we even needed to cover it at all. I haven't used a refresh in real life since JPA first came out...

Hope you enjoy the rest of the book and keep the errata coming smilie.

Kind regards,
Reza

P.S.: It is fine to revive old threads. That way, there's better context and the forum isn't cluttered up with a bunch of duplicate entries...