RequestFactory / collections

89 views
Skip to first unread message

Magno Machado

unread,
Sep 23, 2011, 3:40:43 PM9/23/11
to Google-We...@googlegroups.com
I have an entity with an one-to-many relationship, and a single view on the app where such entities are created, populated and persisted (Using requestfactory).

At first, I thought I should create the requestcontext and instantiate a new proxy of the entity when the view is started, like this:
request = myRequestFactory.fooRequest();
foo = request.create(FooProxy.class);

Then, during the view execution the properties of the entity would be populated (including the relationship)

And when the user press "save", I would call a method on the service to persist the whole entity in a single step, that is: There will be only one service method call

Is this the right way of working with requestfactory?

I had trouble with adding elements to the one-to-many relationship... My code was like this:
BarProxy bar = request.create(BarProxy.class);
bar.setXxx(...);
foo.getItems().add(bar);

But getItems() returns null, so it failed.

Then I created another service method called addBar which takes a Foo and a Bar, and add the Bar to foo.getItems(). So now my client code where I add elements to the collection was like:
BarProxy bar = request.create(BarProxy.class);
bar.setXxx(...);
request.addBar(foo, bar);

And then when the user wants to save, I just call request.persist(foo);

However, as I'm now calling service methods with objects that aren't completely filled, I got validation errors. So, I had to completely disable entity validation using a servicelayer decorator. It seems to work now, but I didn't like how I've done this whole process

Maybe I'm not using requestfactory as it should be used, and that caused my issues. What would be the right way to work?

Aidan O'Kelly

unread,
Sep 23, 2011, 5:25:08 PM9/23/11
to google-we...@googlegroups.com
On Fri, Sep 23, 2011 at 8:40 PM, Magno Machado <mag...@gmail.com> wrote:
> And when the user press "save", I would call a method on the service to
> persist the whole entity in a single step, that is: There will be only one
> service method call
> Is this the right way of working with requestfactory?

Yes. The server side component of RequestFactory will create a 'Foo',
a List of 'Bar's, and call all the setters, including
setItems(listOfBars) on the Foo *before* the save/persist service
method is called, so in your save method you can take care of
persisting your 'items' collection.

> I had trouble with adding elements to the one-to-many relationship... My
> code was like this:
> BarProxy bar = request.create(BarProxy.class);
> bar.setXxx(...);
> foo.getItems().add(bar);
> But getItems() returns null, so it failed.

When creating a proxy on the client side, all fields will be null
initially, so you need to initialize it with an empty/already
populated list.
Its also important to use .with('items') when retrieving or sending an
object graph(ie, calling a service method), as relationships are not
sent over the wire unless you explicitly ask.

Aidan.

Thomas Broyer

unread,
Sep 23, 2011, 5:37:26 PM9/23/11
to google-we...@googlegroups.com
Note that the. with() only applies to return values, not to arguments. I.e. from server to client only.

Aidan O'Kelly

unread,
Sep 23, 2011, 6:38:00 PM9/23/11
to google-we...@googlegroups.com
(not related to OP)
Ah, good to know, so I'm guessing RequestFactory tracks which
relationships you originally retrieved for a given proxy, and only
send these back with subsequent requests.. ?

On Fri, Sep 23, 2011 at 10:37 PM, Thomas Broyer <t.br...@gmail.com> wrote:
> Note that the. with() only applies to return values, not to arguments. I.e. from server to client only.
>

> --
> You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
> To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/MYVEkj1-a6QJ.
> To post to this group, send email to google-we...@googlegroups.com.
> To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
>
>

Thomas Broyer

unread,
Sep 23, 2011, 7:05:05 PM9/23/11
to google-we...@googlegroups.com
No, RF does a diff between the object you retrieved (unmodifiable, passed to context.edit(obj)) and the one you're editing (returned from context.edit(obj)) at the time you fire() your context, and sends that diff over the wire. If you didn't retrieve a property and fills it on the client-side, it'll see that you filled it and will send it to the server. The only exception is ValueProxy: every single property in a ValueProxy is sent, no diff is made, each ValueProxy instance is a distinct "value".

Magno Machado

unread,
Sep 23, 2011, 7:36:56 PM9/23/11
to google-we...@googlegroups.com
Ok, so now I did this:
on view start:
bars = new ArrayList<BarProxy>();
foo = request.create(FooProxy.class);
foo.setBars(bars);

when adding one item:
bar = request.create(BarProxy.class);
bar.setXxx(...);
bars.add(bar);

when saving:
request.persist(foo);
request.fire();

But only foo got persisted, not it's bars

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

Aidan O'Kelly

unread,
Sep 24, 2011, 4:01:10 AM9/24/11
to google-we...@googlegroups.com
On Sat, Sep 24, 2011 at 12:36 AM, Magno Machado <mag...@gmail.com> wrote:

> But only foo got persisted, not it's bars

RequestFactory itself doesn't persist anything, it just synchronizes
the object graph between client & server. How exactly you would
persist a Foo, a list of Bars, and the relationship is dependent on
what data storage you are using, so there needs to be logic inside the
persist() method of Foo, that persists not only the Foo, but any
relationships and their objects.

If you inspect Foo.getItems() inside the Foo's persist() method, a
list of Bars should be there, that's where RequestFactory's part ends.

Aidan O'Kelly

unread,
Sep 24, 2011, 4:09:25 AM9/24/11
to google-we...@googlegroups.com
Yeah, realized the diff mechanism takes care of what problems I was
thinking of shortly after posting, doh.
It does mean, you can set a relationship you never retrieved with
with(), but you can not un-set (null) a relationship unless you
retrieved it, of course, who cares..! (and I didn't check this)

> --
> You received this message because you are subscribed to the Google Groups
> "Google Web Toolkit" group.
> To view this discussion on the web visit

> https://groups.google.com/d/msg/google-web-toolkit/-/szisuiWUylIJ.

Thomas Broyer

unread,
Sep 24, 2011, 11:44:46 AM9/24/11
to google-we...@googlegroups.com
AFAIK, the list is copied when set into the proxy (so that it can be "proxied" itself). You should add to foo.getBars() instead.

(and by "foo only got persisted", I suppose you're saying that getBars() returns null or an empty list in your persist() method, and/or that setBars() is never called?)

David Sanders

unread,
Oct 12, 2011, 4:25:27 AM10/12/11
to google-we...@googlegroups.com
I'm having a very similar issue where my new bars are not being persisted on the server.  When I examine the list from within its setter on the server, I can see that the new bar objects are in the list but the fields are all null, even though I set them explicitly on the client.  Is there something that I'm missing here?

BTW, when I try to debug RF with the dumpPayload flag it shows the payload but in an unreadable format - is there a way to set it to become readable?

Thomas Broyer

unread,
Oct 12, 2011, 5:42:34 AM10/12/11
to google-we...@googlegroups.com


On Wednesday, October 12, 2011 10:25:27 AM UTC+2, David Sanders wrote:
I'm having a very similar issue where my new bars are not being persisted on the server.  When I examine the list from within its setter on the server, I can see that the new bar objects are in the list but the fields are all null, even though I set them explicitly on the client.  Is there something that I'm missing here?

Yes, your looking at the list at the wrong time. Look at it from your persist() (or whatever it's called) method.
 

BTW, when I try to debug RF with the dumpPayload flag it shows the payload but in an unreadable format - is there a way to set it to become readable?

It's JSON, so you can easily pretty-print it (or you can look at it from your browser's developer tools, most of which show JSON in treeviews). At the top-level, "O" stands for operation (setters to be called on domain objects) and "I" for invocations (service method calls). Within "O" you'll find a list of proxies, with "P" being their properties being set. Everything is obfuscated though; you'll find the mapping either in the DeobfuscatorBuilder that the annotation processor (wherever you told it to output the source –defaults to .apt_generated in Eclipse for instance–), or in the RF implementation generated by the GWT compilation (in the -gen folder –yes, you have to recompile, or re-run DevMode, with the -gen option–).
Reply all
Reply to author
Forward
0 new messages