Ways to Avoid DTOs in GWT using Objectify

89 views
Skip to first unread message

digitalsam007

unread,
Feb 5, 2010, 2:31:06 AM2/5/10
to objectify-appengine
Hello Objectify users,

Take a look at the entities below -

Article {
@Id Long id;
Text content;
Date createdOn;
@Parent OKey<User>author;
}

Comment{
@Id Long id;
String content;
String email;
Date commentedOn;
OKey<Article> article;
}

I am trying to create a many-to-One relationship here for Comments-to-
Articles. I kept the Article and Comment separate for performance
reasons.

To get a list of Comments for an article with key articleKey, we can
do something like this -

OQuery<Comment> q =
ObjectifyService.createQuery(Comment.class).filter("article",
articleKey);
List<Comment> comments = ofy.prepare(q).asIterable();

I was thinking of a solution where the Article entity could have a
reference to a list of Comments marked as @Transient like this -

Article {
@Id Long id;
Text content;
Date createdOn;
@Parent OKey<User>author;
@Transient List<Comments> comments;
}

So, when I retrieve the list of comments I could just set the
transient field with the list and trasfer it back to the GWT layer.

My question is, if we want to transfer the comments with the article
to the GWT (View) layer, what would be the best way to do that without
creating any intermediate DTO objects?

PS: Sorry if this post do not directly relate to Objectify.

Matt Quail

unread,
Feb 5, 2010, 3:22:43 AM2/5/10
to objectify...@googlegroups.com
Hi,

That last Article example you gave should give you the behavior you want.

Article {
@Id Long id;
Text content;
Date createdOn;
@Parent OKey<User>author;
@Transient List<Comments> comments;
}

Objectify will see the @Transient and ignore it. But GWT serialization
only looks for the transient keyword, not the @Transient annotation:
http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunication.html#DevGuideSerializableTypes

So that the comments field in that Article class will be ignored by
Objectify, but serialized by GWT.

=Matt

digitalsam007

unread,
Feb 5, 2010, 3:51:21 AM2/5/10
to objectify-appengine
Thanks for the reply. One more question regarding the Text property.
It seems that GWT wont be able to serialize that properly; do you have
any good workaround to handle that? Like automatically converting a
Text to a String type???

On Feb 5, 1:22 pm, Matt Quail <spudb...@gmail.com> wrote:
> Hi,
>
> That last Article example you gave should give you the behavior you want.
>
>  Article {
>    @Id Long id;
>    Text content;
>    Date createdOn;
>    @Parent OKey<User>author;
>    @Transient List<Comments> comments;
>
> }
>
> Objectify will see the @Transient and ignore it. But GWT serialization

> only looks for the transient keyword, not the @Transient annotation:http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunicat...


>
> So that the comments field in that Article class will be ignored by
> Objectify, but serialized by GWT.
>
> =Matt
>

Jeff Schnitzer

unread,
Feb 5, 2010, 4:16:51 AM2/5/10
to objectify...@googlegroups.com
There is no need to use Text in Objectify. If your String is > 500
chars, it will automatically convert the value to and from Text.

However, the code in svn trunk will GWT-serialize all of the basic
datastore types. The query API is different, however - you will want
to build the javadocs ("ant javadoc").

Jeff

digitalsam007

unread,
Feb 5, 2010, 5:04:59 AM2/5/10
to objectify-appengine
You Guys Rock Jeff

On Feb 5, 2:16 pm, Jeff Schnitzer <j...@infohazard.org> wrote:
> There is no need to use Text in Objectify.  If your String is > 500
> chars, it will automatically convert the value to and from Text.
>
> However, the code in svn trunk will GWT-serialize all of the basic
> datastore types.  The query API is different, however - you will want
> to build the javadocs ("ant javadoc").
>
> Jeff
>

digitalsam007

unread,
Feb 5, 2010, 6:04:42 AM2/5/10
to objectify-appengine
Sorry to bother you again and again Jeff...

But what alternative do you suggest for Blob types? Do you have
anything in the wiki that mentions this? It would be useful to have!

On Feb 5, 2:16 pm, Jeff Schnitzer <j...@infohazard.org> wrote:

> There is no need to use Text in Objectify.  If your String is > 500
> chars, it will automatically convert the value to and from Text.
>
> However, the code in svn trunk will GWT-serialize all of the basic
> datastore types.  The query API is different, however - you will want
> to build the javadocs ("ant javadoc").
>
> Jeff
>

Jeff Schnitzer

unread,
Feb 5, 2010, 1:25:58 PM2/5/10
to objectify...@googlegroups.com
The Blob class GWT serializes as-is on Objectify svn trunk, but this
does bring up a good point - should we automatically convert byte[] to
Blob?

Right now byte[] will get converted to a Collection<Byte>, which
indexes each byte value. Probably not useful to anyone.

Autoconverting byte[] to Blob would not be orthogonal with how we
treat other arrays (long, short, String, etc) but it would be more
useful and probably less surprising to the user if we just treat
byte[] like a blob.

Jeff

Matt Quail

unread,
Feb 5, 2010, 5:55:52 PM2/5/10
to objectify...@googlegroups.com
I think it would be useful if you could *ask* Objectify to autconvert
byte[] as Blob, but should we do it automatically? You can query
against the individual values of a Collection<Byte>, but not a Blob.

Is there a lesson there for how we autoconvert large Strings to Text?
Should we never autoconvert indexable String/byte[] fields to
Text/Blob -- only convert them for @UnIndexed perhaps?

I'm not sure if we should autoconvert byte[] to Blob. But I think it
would always be okay on load to convert Blob to byte[].

=Matt

Jeff Schnitzer

unread,
Feb 5, 2010, 6:11:55 PM2/5/10
to objectify...@googlegroups.com
The design principle I wish to apply is the "principle of least
surprise". Given a class that looks like this:

class Foo {
@Id Long id;
byte[] data;
}

Which gotcha is more likely to produce a surprised user?

1) The user expected this to be written as a Collection<Byte> in the
datastore and the data got written as a binary blob instead.

2) The user expected this to be written as a binary blob and it got
written as a Collection<Byte> (indexed, with a 5k limit).

I'm guessing that for every developer in category #1, there will be
999 in category #2. It may not be orthogonal with treatment of char[]
or short[], but java programmers are heavily conditioned to the use of
byte[] as a binary array.

Put it this way: Even if we document the hell out of this issue
(byte[] is not Blob!) we will still end up with lots of programmers
mistakenly using byte[] as a blob field because that is what they are
conditioned to expect. Unfortunately this will work - mostly - and
sometime in production they will realize they screwed up and need to
rebuild their data. On the other hand, there may never actually be
someone that actually wants a Collection<Byte>.

So, I think that we should do autoconversion of byte[] to Blob (and
vice-versa). We can leave Byte[] as an actual indexed collection of
Byte objects if there is someone in the universe that actually wants
this behavior.

Jeff

Jon Stevens

unread,
Feb 5, 2010, 6:38:06 PM2/5/10
to objectify...@googlegroups.com
So, I think that we should do autoconversion of byte[] to Blob (and
vice-versa).  We can leave Byte[] as an actual indexed collection of
Byte objects if there is someone in the universe that actually wants
this behavior.

Jeff

+1 . I also agree with your style of logic.

jon

digitalsam007

unread,
Feb 6, 2010, 11:59:26 PM2/6/10
to objectify-appengine
+1 for your ideas Jeff

I am still wondering how do I persist Image as Blob objects from GWT
to Datastore via Objectify. You mentioned about the Blob class defined
in the SVN, but how do we use it?

> On Fri, Feb 5, 2010 at 2:55 PM, Matt Quail <spudb...@gmail.com> wrote:
> > I think it would be useful if you could *ask* Objectify to autconvert
> > byte[] as Blob, but should we do it automatically? You can query
> > against the individual values of a Collection<Byte>, but not a Blob.
>
> > Is there a lesson there for how we autoconvert large Strings to Text?
> > Should we never autoconvert indexable String/byte[] fields to
> > Text/Blob -- only convert them for @UnIndexed perhaps?
>
> > I'm not sure if we should autoconvert byte[] to Blob. But I think it
> > would always be okay on load to convert Blob to byte[].
>
> > =Matt
>

> > On Sat, Feb 6, 2010 at 5:25 AM, Jeff Schnitzer <j...@infohazard.org> wrote:
> >> The Blob class GWT serializes as-is on Objectify svn trunk, but this
> >> does bring up a good point - should we automatically convert byte[] to
> >> Blob?
>
> >> Right now byte[] will get converted to a Collection<Byte>, which
> >> indexes each byte value.  Probably not useful to anyone.
>
> >> Autoconverting byte[] to Blob would not be orthogonal with how we
> >> treat other arrays (long, short, String, etc) but it would be more
> >> useful and probably less surprising to the user if we just treat
> >> byte[] like a blob.
>
> >> Jeff
>

Jeff Schnitzer

unread,
Feb 7, 2010, 2:11:56 PM2/7/10
to objectify...@googlegroups.com
Since even Blob types have a 1M limit, you may not want to store
images in the datastore. Have you considered the new blobstore
service?

Jeff

digitalsam007

unread,
Feb 9, 2010, 5:10:38 AM2/9/10
to objectify-appengine
Well yes, I have seen that google now provides 50M (max) file size
storage using Blobstore.
However, as far as I know, it is enabled only for paid services.

And I am currently saving a small size images only ( below 1M) so,
datastore wont be so much a problem. Can I use the GWT enabled classes
Blog / SmallBlob as a entity property to save image data?

On Feb 8, 12:11 am, Jeff Schnitzer <j...@infohazard.org> wrote:
> Since even Blob types have a 1M limit, you may not want to store
> images in the datastore.  Have you considered the new blobstore
> service?
>
> Jeff
>

Jeff Schnitzer

unread,
Feb 10, 2010, 1:33:34 PM2/10/10
to objectify...@googlegroups.com
Sure, it should work just fine.

Jeff

Reply all
Reply to author
Forward
0 new messages