On Friday, March 11, 2011 11:43:48 AM UTC+1, Jens wrote:
>
> Hi,
>
> I currently have some problems with entity version checks / optimistic 
> locking using JPA on server side and I wonder how RequestFactory would 
> handle my problem.
>
> Currently the application I am working on has an auto save mechanism. That 
> means each time the user changed some data the application will wait a 
> couple of milliseconds and if no additional changes are made during this 
> time the application sends a save command (command / dispatch pattern) to 
> the server. The server then loads the JPA entity from the database and 
> compares its entity version with the one provided by the client entity that 
> was send with the save command. If they match, data will be copied from 
> client entity to the JPA entity and then saved to our database. When the 
> entity is saved we return the new entity version to the client application 
> which updates it in the client entity object. If they do not match, an 
> exception will be thrown and the client application reloads the object and 
> updates the UI because the database contains newer data. Our server is 
> pretty stateless and we have one transaction per request.
> So its similar to RequestFactory. We have a client entity class and a JPA 
> entity and copy data between them on server side (along with some 
> computations if needed).
>
> Now our problem: As we do our auto save quite instant (about 100-300 ms 
> after the last user input) it may happen that we fire two or more save 
> commands without getting a response from our server because the network 
> connection is bad (basically the round trip time would be longer as our auto 
> save timer / 100-300ms). Thus the second save command will fail because the 
> first one results in an updated entity version in our database but the 
> client does not now about it yet and thus the second save command contains 
> the same entity version as the first one.
>

Maybe you should delay autosave requests to until the previous one has 
returned?
 

> How would RequestFactory handle such a situation? What happens if you call 
> xxxRequest.persist().using(object).fire() twice without having received a 
> result during both calls (what could happen if we integrate RF instead of a 
> command pattern)?
>

Well, first, you can only edit() a proxy once at a time (i.e. in a single 
RequestContext). Second, when you fire() a RequestContext, the edit()ed 
proxies are locked until the response comes back.
This basically means that if you have to lock the form while you autosave 
it.
I'd suggest you file an enhancement request so you could, e.g. flush the 
editor to a different object/proxy than was passed to initialize it. That 
way, you could display() the proxy (so it's not edit()ed), and then flush 
into an edit()ed version. You'd still have to block until the response come 
before doing another autosave; and worse, before doing a save(), which means 
the user would have to wait for the autosave to finish before it can 
explicitly save the form *and go away!*
In GWT 2.3, editors will be "visitable" (using a visitor pattern), so it 
might be possible to implement the above this way, but I'm not even sure…

I know that RequestFactory currently does no real optimistic lock check (
> http://code.google.com/p/google-web-toolkit/issues/detail?id=6046) because 
> it somehow disappeared in the source code. But how would it handle entity 
> versions to make sure optimistic locking works? Are entity versions stored 
> in the generated proxy classes or is there a server side map that remembers 
> all entity proxys with their entity versions that have been delivered to the 
> client?
>

Entity versions are sent to/from the client along with the ID. It's a 
serialized and encoded version though, because a version can be any kind of 
object (RequestFactory does a toString() on it, and then base64-encode it).
RequestFactory would have to either: find() with the ID and version (in 
String form) and let you "parse" the version back into you object type (but 
that would lock RF into always transforming the version to a String), or 
find() the entity as today and then ask for its version, serialize it and 
compare with the version sent by the client (same comparison as is done 
before returning objects to the client, to "generate" the appropriate 
EntityProxyChange events on the client).
 

> How do you do optimistic checking in your application and how do you have 
> solved this issue?
>

We don't actually; but we're in a special case that users first have to 
explicitly lock an object (actually, create a private working copy) before 
they can edit it; so a given user can only be in conflict with "himself"; 
and using the application in multiple tabs/windows is an officially 
unsupported use case (yes, we're lucky ;-) ).

-- 
You received this message because you are subscribed to the Google Groups 
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-web-toolkit?hl=en.

Reply via email to