RequestFactory, Objectify, saving a new object with collections

62 views
Skip to first unread message

Richard Berger

unread,
Nov 23, 2010, 2:23:00 PM11/23/10
to Google Web Toolkit
Goal: Save an object an associated collection
How to do this with Request Factory and Objectify?

I have an object that looks like:
Commitment.java (in com.br.commit2.server.domain)
public class Commitment {
@Id private Long id;
private String title;
// other simple fields
private Integer version;

// Methods exposed through Request factory

// Getters, setters
}

Since I am trying to use RequestFactory, I also have:
CommitmentProxy.java (in com.rb.commit2.shared)
@ProxyFor (Commitment.class)
public interface CommitmentProxy extends EntityProxy {
public String getTitle();
public void setTitle(String title);
// rest of interface
}

Also have
public interface CommitmentSystemRequestFactory extends RequestFactory
{
CommitmentRequest commitmentRequest();
...
}

And...
@Service (Commitment.class)
public interface CommitmentRequest extends RequestContext {
Request<Long> countCommitments();
// Other methods, implemented in Commitment.java above)
}

Finally, in my Commit2Binder.java, I have code that works to create a
commitment when a button is clicked (this is just a test app)
CommitmentRequest request = requestFactory.commitmentRequest();
CommitmentProxy newCommitment =
request.create(CommitmentProxy.class);
newCommitment.setTitle("Test Objectify title");
newCommitment.setDescription("Test Objectify Description");
Request<Void> createReq =
request.persistCommitment().using(newCommitment);

createReq.fire(new Receiver<Void>() {
@Override
public void onSuccess(Void response) {
Window.alert("Created Commitment!");

}
});

Surprisingly enough it all works fine. Now, I want to model a new
object, a user with two collections of the Commitment object above.
These are unowned collections. Following the objectify-appengine/
wiki//IntroductionToObjectify#Relationships, I create CommitUser

public class CommitUser implements Serializable {
private static final long serialVersionUID = 1L;
@Id private Long id;
private String googleEmail;
...
private Key<Commitment>[] dueByMeCommitments;
private Key<Commitment>[] dueToMeCommitments;
}

And the related CommitUserProxy
@ProxyFor (CommitUser.class)
public interface CommitUserProxy extends EntityProxy {
public int getUserLevel();
....
}

And a new Request Interface
@Service (CommitUser.class)
public interface CommitUserRequest extends RequestContext {
InstanceRequest<CommitUserProxy, Void> persistCommitUser();
}

And add a line to my CommitmentSystemRequestFactory.java for
CommitUserRequest.

Now, in my Commit2Binder, I want to create a new CommitUser - empty
collections are fine to start with. But the code I have, essentially
the code that works for creating a Commitment, fails. The code is:
CommitUserRequest request = requestFactory.commitUserRequest();
CommitUserProxy newCommitUser =
request.create(CommitUserProxy.class);
newCommitUser.setGoogleNickname("Richard");
newCommitUser.setGoogleEmail("richar...@gmail.com");
newCommitUser.setUserLevel(1);
newCommitUser.setDueByMeCommitments(null);
newCommitUser.setDueToMeCommitments(null);
Request<Void> createReq =
request.persistCommitUser().using(newCommitUser);

createReq.fire(new Receiver<Void>() {
@Override
public void onSuccess(Void response) {
Window.alert("Created User!");

}
@Override
public void onFailure(ServerFailure error) {
Window.alert(error.getMessage());
}
});
;

The failure occurs when the rquest is fired and the error is:
Caused by: java.lang.ClassCastException:
sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl cannot be
cast to java.lang.Class
If I remove the calls to setDueByMeCommitments, setDueToMeCommitments
I get the same error.

I start to look at other ideas, but it starts to seem that I am going
down the wrong path, since this should be something relative. Any
pointers and thoughts would be greatly appreciated.

Thanks!
RB

David Chandler

unread,
Nov 23, 2010, 3:26:16 PM11/23/10
to google-we...@googlegroups.com
Hi Richard,

RequestFactory doesn't yet support arrays. Use List<T> instead. Also
ensure that your Proxy doesn't expose the Objectify Key type, as only
entity types and a few value types are supported until 2.1.1.

/dmc

> --
> 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.
>
>

--
David Chandler
Developer Programs Engineer, Google Web Toolkit
http://googlewebtoolkit.blogspot.com/

Richard Berger

unread,
Nov 23, 2010, 5:23:33 PM11/23/10
to Google Web Toolkit
Thank you for the quick and clear reply which completely fixed my
problem. On a higher level, when support for Keys is added, should I
use the Key or the Entity? I can see that there may be some value in
just having the Key and getting the Entity when I need it - although
it seems like I will nearly always be needing the Entity. But perhaps
I am missing some key distinction.

Thanks so much for taking the time to share your advice!
RB
> >        newCommitUser.setGoogleEmail("richardlan...@gmail.com");
> > For more options, visit this group athttp://groups.google.com/group/google-web-toolkit?hl=en.

David Chandler

unread,
Nov 23, 2010, 5:44:32 PM11/23/10
to google-we...@googlegroups.com
You're welcome, Richard, glad to help.

My understanding is that Objectify always uses Keys to express
relationships. If you want to retrieve the entity directly, you can
add a getter/setter that calls Objectify to get / put an entity by its
Key. These helper methods are likely what you would expose in the
EntityProxy so client-side code won't have any references to Key. This
works today.

/dmc

> For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Richard Berger

unread,
Nov 24, 2010, 4:25:32 PM11/24/10
to Google Web Toolkit
Thanks again - I will give that a try.... RB

On Nov 23, 2:44 pm, David Chandler <drfibona...@google.com> wrote:
> You're welcome, Richard, glad to help.
>
> My understanding is that Objectify always uses Keys to express
> relationships. If you want to retrieve the entity directly, you can
> add a getter/setter that calls Objectify to get / put an entity by its
> Key. These helper methods are likely what you would expose in the
> EntityProxy so client-side code won't have any references to Key. This
> works today.
>
> /dmc
>
Reply all
Reply to author
Forward
0 new messages