On 9 nov, 21:13, Jack <
jack.kenn...@gmail.com> wrote:
> We are facing a few challenges regarding the use of the RequestFactory
> infrastructure with existing RDBMS tables and I wanted to be sure that
> we understood the current restrictions as we would need to communicate
> those restrictions to developers using our tools.
>
> If there are any opportunities to assist or contribute to GWT in
> support of the following cases I would certainly be happy to help.
>
> Specific Challenges:
>
> Tables without ID or Version fields would require modifications to the
> schema and updates to all existing records
> - The table must be updated to add the id and version fields (or have
> the JPA provider auto add the new fields)
> - This would also mean that the existing data in the DB would need to
> be updated to so that each record has the version field filled in with
> a default value
> -The newly added ID value for each existing record in the table would
> also have to be updated with a value that is unique for each record
The server-side domain objects are required to have a getId() and
getVersion() methods, but that doesn't mean they have to map to RDBMS
table fields. And, the getVersion() isn't required to returned a
"sensible" value, it can return 'null' if you don't have/want a notion
of version and optimistic locking (at the RF level).
> Tables that use multiple existing fields for unique identification of
> each record are not supported
> -Many existing RDBM tables use multiple fields in their keys to
> uniquely identify a record
And many think this is bad design, but that's another story.
To make it work with RF, you can have your server-side domain object's
getId() return a concatenation of these fields as a String.
> Tables with an existing field named 'id' that is a String can not have
> the id value passed from the client on create
> -The JSONRequestProcessor has a method to get the String value for the
> "create" operation that returns null by default
> -If the value of the ID was passed in from the client it would be
> ignored and not bound to a newly created Entity because the
> JSONRequest handling assumes the ID fields to be auto generated
I believe it's supported if your EntityProxy has a setId(), but I
haven't actually checked.
My understanding is that the JsonRequestProcessor serializes the Class
name and getId() (this is known as the stableId) when sending an
object from server to client (it also sends the getVersion for
optimistic locking, see below).
When the client sends an object to the server, either it sends back
that stableId (along with the version) or it makes up one that
explicitly says "this was created on the client-side" (also known as
"future Id").
On the server-side, if the received stableId isn't a "future Id", it
extracts the Class and Id from it and then retrieves the object from
the datastore using the Class's static find method passing the
deserialized Id as argument; and finally it checks that the getVersion
is the same as the version it received back from the client: if it's
different it aborts and tells the client that the server object has
changed, otherwise it continues, applying the changes to the object
before finally calling the method/operation.
If the received stableId was a "future Id", the JsonRequestProcessor
extracts the Class from it and instantiates a new instance using the
no-args constructor; it then applies the changes (setters) before
calling the method/operation. The "future Id" also contains a numeric
identifier so the object can be referenced in other objects in the
same request, and more than one "future" object can be sent in the
same request.
In the "setters" phase of both cases, I don't think there's a special-
case for "setId".
Now, after the method/operation, the JsonRequestProcessor has to check
whether the object has change so it can send the client a notification
if it is the case; it uses the getVersion if it's not 'null', or
otherwise compares what all the getters of the domain object return
(it would have previously stored the values in a "delta value store",
just after getting the object from the datastore); but for "future"
objects, I think it sends the "notification" in every case. Finally,
there's a special check for finding "deleted" objects: the find()
method is called once more (using the "stable Id" serialized Id I
guess) to check whether it returns an object back or null (meaning the
object has been deleted, so a "notification" is sent back to the
client).
This is my understanding from my previous readings of
JsonRequestProcessor's code (before the overhaul in the trunk), maybe
I misunderstood how it works, and maybe it has changed since then
(i.e. in the future 2.1.1 release); so you'd better double check!