Sub entities not being filled in

23 views
Skip to first unread message

Patrick Julien

unread,
Oct 3, 2010, 6:11:37 PM10/3/10
to google-web-tool...@googlegroups.com
I'm getting used to this editor framework and I like it a lot,
unfortunately, I think I've stumble upon a blocker for me.

EntityProxy's that contain collections are not being filled in. So
you can send up an object graph in one shot in order to save it.
Which is great.

Unfortunately, on return, the object graph only contains the root.
This is because in JsoRequestProcessor.requestedProperty, it does:

if (EntityProxy.class.isAssignableFrom(leafType)) {
return propertyContext.hasProperty(p.getName());
}

to check if child entities should be included but that's an empty set
so it always returns false

If it wasn't, we have TODO here TODO: use the properties
* that should be coming with the request.

that says this thing should eventually be able to do this but wouldn't
the safest behavior for now to include all the contents of the Entity
that are featured in EntityProxyId? I'm stuck at this point.

Ray Cromwell

unread,
Oct 3, 2010, 7:10:20 PM10/3/10
to google-web-tool...@googlegroups.com

Any relational (non-value fields) are by default not sent back with a request, you must request them with the with() method, e.g. with("superVisor"). Just because you sent some object over with that field, doesn't mean that the field will also be returned to you, because a method could potentially return a very large set of objects, e.g.

Request<List<EmployeeProxy>> getEmployeesFrom(EmployeeProxy boss); 

Here I am passing the manager's proxy, and it might have a Collection<EmployeeProxy> managedEmployees on it, but if I'm only interested in the names of the people that 'boss' manages, I don't want to automatically return the 'managedEmployees' field of each returned object, even if it was present on boss, so instead, you write

getEmployeesFrom(boss).with("managedEmployees").fire(...) if you want that field.

Perhaps the editor framework is not setting up these with() calls as it should be?

Patrick Julien

unread,
Oct 3, 2010, 7:17:10 PM10/3/10
to google-web-tool...@googlegroups.com
Is there a wildcard value? I don't want the all the fields when
listing but when I go in edit details, I do

> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors

Patrick Julien

unread,
Oct 3, 2010, 7:24:03 PM10/3/10
to google-web-tool...@googlegroups.com
Yeah, because even with using with(). The problem is the entire
object graph isn't there

So I have a practice that has offices and each office has phones.

So if I ask for offices. It fills in the offices but the phones
inside it are not. This could get laborious if I need to do this
manually for each editing activity

BobV

unread,
Oct 3, 2010, 8:22:13 PM10/3/10
to google-web-tool...@googlegroups.com
On Sun, Oct 3, 2010 at 7:24 PM, Patrick Julien <pju...@gmail.com> wrote:
> Yeah, because even with using with().  The problem is the entire
> object graph isn't there
>
> So I have a practice that has offices and each office has phones.
>
> So if I ask for offices.  It fills in the offices but the phones
> inside it are not.  This could get laborious if I need to do this
> manually for each editing activity

Use RequestFactoryEditorDriver.getPaths();


interface MyOfficeDriver extends
RequesFactoryEditorDriver<OfficeProxy, OfficeEditor> {}

MyOfficeDriver driver = GWT.create(MyOfficeDriver.class);
driver.initialize(requestFactory, editor);
requestFactory.officeService().fetchOffice(1234).with(driver.getPaths()).to(receiver).fire();


--
Bob Vawter
Google Web Toolkit Team

Patrick Julien

unread,
Oct 3, 2010, 8:38:26 PM10/3/10
to google-web-tool...@googlegroups.com
Getting there. So now getPaths() gets me the data for my offices and
patients but not the phones inside the offices.

Since offices is using my own composite editor, I'm going to assume
that's where the problem is

> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors

Patrick Julien

unread,
Oct 3, 2010, 9:02:43 PM10/3/10
to google-web-tool...@googlegroups.com
No, it's not just me, anything one level deep doesn't get picked up.

So my offices also have on address and it's not in the getPath() array
either. Even if it was, what's the syntax for sub path elements?

Ray Cromwell

unread,
Oct 3, 2010, 9:07:21 PM10/3/10
to google-web-tool...@googlegroups.com

the syntax of with() is with("property.subProperty.subSubProperty", "property2.subProperty2.subPropertyProperty2"). Bob can answer the question as to how to make deeply composited editors do the right thing.


Patrick Julien

unread,
Oct 3, 2010, 9:47:49 PM10/3/10
to google-web-tool...@googlegroups.com
I'm still having difficulties even with this syntax, again the
collections seem to be the problem

so having "offices" give me back all my offices.

but putting "offices.address", or "offices.office.address" or
"office.address" still gives me null

> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors

Sam Gross

unread,
Oct 4, 2010, 12:33:48 AM10/4/10
to google-web-tool...@googlegroups.com
I also ran into a bug today where sub entities were not always
deserialized. The problem is in that entries in related objects may
refer to entities that haven't been deserialized yet if the referenced
entities occur later in related objects.

Splitting AbstractRequestContext.processReturnRecord so that it first
creates all the proxies before mutating any of them seemed to fix the
problem.

-Sam

> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors

Ray Cromwell

unread,
Oct 4, 2010, 2:11:29 AM10/4/10
to google-web-tool...@googlegroups.com

Thanks Sam, yeah, this is a big bad bug. 


Patrick Julien

unread,
Oct 4, 2010, 9:41:20 AM10/4/10
to google-web-tool...@googlegroups.com
For the editor part, I can see in the generated code for my editor that

public static void traverseEditor(com.*.client.ui.EditorContainer
editor, String prefix, java.util.List<String> paths) {
}

is completely empty

but in this case, EditorContainer contains OfficeEditor because it's a
composite. OfficeEditor has one AddressEditor and a
HasDataEditor<Phone>

so getPath() is currently buggy unless there's a way I can fill in my
own traverseEditor somehow

Patrick Julien

unread,
Oct 4, 2010, 12:07:22 PM10/4/10
to google-web-tool...@googlegroups.com
Bob,

any suggestions for a work around for the moment?

Patrick Julien

unread,
Oct 4, 2010, 5:14:34 PM10/4/10
to google-web-tool...@googlegroups.com
As an update to this issue, I can confirm that I have an editor
working in another scenario where the depth level doesn't go beyond,
well, 1 I guess.

So I an editor, and it has a list in it but the list doesn't contain
other EntityProxy's

The two issues still remain:

driver.getPath() isn't able to completely scan an editor tree when it
contains CompositeEditor's that, they themselves, have more editors in
their hierarchy

It's not possible to request sub-properties when using collections
manually. It just doesn't work. The example I gave were trying to
get the name of an office inside a collection, putting

offices
office
offices.name
office.name
offices.office.name

just doesn't work.


On Mon, Oct 4, 2010 at 9:41 AM, Patrick Julien <pju...@gmail.com> wrote:

BobV

unread,
Oct 4, 2010, 5:32:56 PM10/4/10
to google-web-tool...@googlegroups.com
Your feedback has been very helpful in finding out where the weak
points in our APIs and implementations are.

> driver.getPath() isn't able to completely scan an editor tree when it
> contains CompositeEditor's that, they themselves, have more editors in
> their hierarchy

I'm thinking about how to solve this one, since an uninitialized
CompositeEditor won't have any sub-editors to query.

> It's not possible to request sub-properties when using collections
> manually.  It just doesn't work.  The example I gave were trying to
> get the name of an office inside a collection, putting

RayC is looking at this.

Ray Cromwell

unread,
Oct 4, 2010, 5:46:02 PM10/4/10
to google-web-tool...@googlegroups.com

The following test case passes:

public void testCollectionSubProperties() {
    delayTestFinish(DELAY_TEST_FINISH);
    simpleFooRequest().getSimpleFooWithSubPropertyCollection().with(
        "selfOneToManyField.fooField").fire(new Receiver<SimpleFooProxy>() {
      @Override
      public void onSuccess(SimpleFooProxy response) {
        assertEquals("I'm Here",
            response.getSelfOneToManyField().get(0).getFooField().getUserName());
      }
    });
  }

on the server:
 public static SimpleFoo getSimpleFooWithSubPropertyCollection() {
    SimpleFoo foo = new SimpleFoo();
    SimpleFoo subFoo = new SimpleFoo();
    SimpleFoo subSubFoo = new SimpleFoo();
    subFoo.setFooField(subSubFoo);
    subSubFoo.setUserName("I'm here");
    subSubFoo.persist();
    subFoo.persist();
    foo.persist();
    foo.setSelfOneToManyField(Arrays.asList(subFoo));
    return foo;
  }

If you have a class that looks like this:

public class Company {
   List<Office> offices;
}

public class Office {
  Employee siteManager;
}

Then the correct way to query for siteManager is:

with("offices.siteManager")

With is a nothing more than a filter on names, it doesn't care if something is a collection, or an entity, just whether or not the name matches.

-Ray

Patrick Julien

unread,
Oct 4, 2010, 5:57:27 PM10/4/10
to google-web-tool...@googlegroups.com
I don't know what to tell you, I'm going to have to look at this again
because it just does not work for me

> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors

Patrick Julien

unread,
Oct 4, 2010, 5:56:14 PM10/4/10
to google-web-tool...@googlegroups.com
On Mon, Oct 4, 2010 at 5:32 PM, BobV <bo...@google.com> wrote:
> Your feedback has been very helpful in finding out where the weak
> points in our APIs and implementations are.
>
>> driver.getPath() isn't able to completely scan an editor tree when it
>> contains CompositeEditor's that, they themselves, have more editors in
>> their hierarchy
>
> I'm thinking about how to solve this one, since an uninitialized
> CompositeEditor won't have any sub-editors to query.


You're using code generation for the other parts. What I mean by that
is that you generate the method

public static void traverseEditor(com.*.client.ui.EditorContainer
editor, String prefix, java.util.List<String> paths) {
}

and that has content that was made at compile time, not run time.
Here, the editor you're looking for is right there in CompositeEditor

CompositeEditor<T, C, E extends Editor<C>>

So whatever E is the children. Is that not suitable here also?

Patrick Julien

unread,
Oct 4, 2010, 8:21:42 PM10/4/10
to google-web-tool...@googlegroups.com
OK, this also works for me, where it breaks down is more collections

So I go back to practice, offices and phones

class Practice { private List<Office> offices; }
class Office { private List<Phone> phones; }

practive is unique and has a list of offices

What I get back has all the practice seeded. All the offices are
seeded and it has all its values but phones is null.

If I add "offices.phones", it works, I get a non null list of phone
handles but the values on the handles are not set.

Now I manually add, in addition to "offices.phones",
"offices.phones.number" the value of number is still null

I believe this respect the syntax you outlined here. I can confirm on
the server in json request processor on the server that the phone
entities are there and have values when processed but the
subProperties map in RequestProperty is null so it returns false when
it tests if it should include these values or not

> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors

Ray Ryan

unread,
Oct 3, 2010, 7:20:50 PM10/3/10
to google-web-tool...@googlegroups.com
At the moment we always fetch all non-entities, and only treat with() as additive, to add related entities into the mix.

I'm a bit concerned about that, actually. With the RF overhaul we no longer have a client side cache to confuse things, so I wonder if we should try to get sparse DTOs in place before people get used to the current sloppiness. Kind of late in the day, I know.

Ray Ryan

unread,
Oct 4, 2010, 2:15:32 PM10/4/10
to google-web-tool...@googlegroups.com
https://jira.springsource.org/browse/ROO-1488

On Mon, Oct 4, 2010 at 11:13 AM, Ray Ryan <rj...@google.com> wrote:
Bob is in transit today. We're working on a fix.



Ray Ryan

unread,
Oct 3, 2010, 7:18:41 PM10/3/10
to google-web-tool...@googlegroups.com
The editor framework can give you the info for the with calls, but it's up to you to use it. If you want everything, put the contents of RequestFactoryEditorDriver.getPaths() into your with() call.


Ray Ryan

unread,
Oct 4, 2010, 2:13:41 PM10/4/10
to google-web-tool...@googlegroups.com
Bob is in transit today. We're working on a fix.


Ray Cromwell

unread,
Oct 7, 2010, 4:57:37 PM10/7/10
to google-web-tool...@googlegroups.com

Patrick,
  Are you using an ORM like hibernate or JDO? One of my concerns is, unless you wrap the entire request in an transaction, the result of any find() calls within JsonRequestProcessor are going to be detached objects. Different ORMs have different pre-fetched semantics, for example, some of them will by default, fetch 1-level deep references. After detachment, generally trying to retrieve a relational field returns null.  JsonRequestProcessor is ORM agnostic, so it is generally up to the developer to ensure that objects will be completely filled out or lazily fillable before RequestFactory tries to serialize them.


Patrick Julien

unread,
Oct 7, 2010, 5:03:20 PM10/7/10
to google-web-tool...@googlegroups.com
r8965 fixed the remaining issue. The other issue was on the AutoBean
itself and was previously fixed. However, I believe I have found
another issue in AbstractAutoBean which I just posted.

> --
> http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply all
Reply to author
Forward
0 new messages