PDA

View Full Version : BaseModel vs BaseTreeModel for RPC, and what's this RpcMap stuff?


baluba
04-30-2008, 12:34 PM
- The attached code works fine. (The service code is not included, it just returns a list of the shown User objects)

- If I change the model objects User and Role to inherit from BaseModel the service call fails, the GWT Serializer complains about the Role class not being serializable...???

So, currently, if you write your own model class extending BaseModel, you can't set a property on it which holds a collection of another BaseModel class. Is this a bug or a result of GWT architecture and that RpcMap thing defined in the BaseModelData class?

The difference between a BaseModel and BaseTreeModel is that the latter has a ArrayList of children (TreeModels). So for some reason this makes the GWT rpc work.



public class RpcProblem implements EntryPoint {

static public class Role extends BaseTreeModel {
public Role() { }
public Role(String code) { set("code", code); }
}

static public class User extends BaseTreeModel {
public User() { }
public User(String username) { setUsername(username); }
public void setUsername(String name) { set("username", name); }
public void setRoles(List<Role> roles) { set("roles", roles); }
public String getName() { return (String)get("name"); }
}


public void onModuleLoad() {
Viewport viewport = new Viewport();

Button button = new Button("TestRpc", new SelectionListener() {
public void componentSelected(ComponentEvent ce) {
TestServiceAsync service = TestService.App.getInstance();
service.getUsers("whoever", new AsyncCallback() {
public void onFailure(Throwable throwable) {
Window.alert("rpc failed: " + throwable.getMessage());
}

public void onSuccess(Object o) {
List<User> users = (ArrayList<User>) o;
Window.alert("rpc succeeded, num returned: " + users.size());
}
});

}
} );

viewport.add(button);
viewport.layout(true);
RootPanel.get().add(viewport);
}
}

dangeruss
05-01-2008, 12:30 PM
I'm not sure if this helps, but here's my crude understanding:

I've been using RpcMap in place of Map, because when I do RpcMap<String,Object>, the object gets through rpc without worrying about serialization (i think with a Map<String,Object>, this doesnt work?).

I've also been using Record (extends Model) for my objects because you can construct it with a map of string properties versus object values. I load it with a map that my database library (jackcess) gives me from database rows.

Could you just replace "extends BaseTreeModel" with "extends Record"?

baluba
05-01-2008, 03:25 PM
Thanks a lot for the hints. I will try your suggestions.

I was actually using a List, but I could always use a map because even if I don't have a key I can just use a counter...

cheers!

baluba
05-02-2008, 06:46 AM
Hi,

Yes it works when I inherit from Record, which is basically is just a decorator for a BaseModel anyway, with some transactional facilities needed in a Store.
But I don't like to make my model objects of Record type with all that extra Store related baggage.

For the given example another workaround that worked was to change the signature of my service call, letting it return List<Record> instead of List<User>, thus the service wrap seach User in a Record before it is placed in the returned list, and in the client they are unwrapeped using Record.getModel(). With this approach my model objects could remain BaseModel types, and their properties could also be collections of other BaseModel types like in the example.I suspect there is some simple thing I can do with my model objects to fix all this, but I don't get it...

bgmoon
10-02-2008, 08:59 AM
You should inherit IsSerializable from any class that you want to transport via RPC. That should fix your problem.

gslender
10-02-2008, 05:06 PM
You should inherit IsSerializable from any class that you want to transport via RPC. That should fix your problem.

You only need to inherit java.io.Serializable since GWT 1.5