On 26 Jan 2010, at 13:37, Jeff Schnitzer wrote:

I can't resist a conversation about framework design philosophy :-)


Oh go on then.  Just a quickie.

This sort of binding (property of List<Photo>) can be convenient in
some applications, and as a longtime Hibernate user I got used to
working like this.  But I don't like this abstraction in AppEngine.
Yes, for some apps you might be able to remove the "pollution" of
framework classes like Key (or OKey), but it comes with a price.

Twig and Objectify operate at very different levels of abstraction. With Objectify you code at a lower level very aware of what is happening at the datastore level. It involves more work but, as you point out, if something goes wrong - it goes wrong in your own code where you are in a better position to handle it.

With Twig you operate at a higher level that makes the persistence layer almost completely transparent. One major advantage of this is that you can change the way the data is stored (i.e. embedded or separate entity) without changing your code. Making such a change with Objectify means you need to rewrite your reference handling code yourself.


A one-to-many relationship between Album and Photo has several
"standard" representations in AppEngine:

* The Photo could have a Key property pointing to Album
* The Photo could have a parent ancestor in its Key which points to the Album * The Album entity could have a List<Key> property pointing to its Photos

Each choice has a dramatic impact on performance, what can be done in
a transaction, and how you do queries that simply cannot be glossed
over or abstracted away.

This is why you configure what type of relationship is used using: @Embed, @Entity(PARENT), @Entity(CHILD) or @Entity(INDEPENDENT)

So you have the flexibility to choose configuration _without_ rewriting your code. Very important difference.

Currently the first type of representation is not an option. I do want to add this as it makes very large collections that change often much more efficient. When it is added you could reconfigure your data schema by changing a single annotation. Such a change in Objectify would require the developer to rewrite their entire data layer

Which does the List<Photo> represent?
Furthermore, is List<Photo> a proxy or did the photos get fetched
along with the Album?  Can I serialize the Album or do I need to
detach it?

Yes instances are just normal POJOs so no problems serializing. I do this myself with GWT.

Currently, lazy references are not supported... its a very important feature on the TODO list.

Even worse, there are also two more possible representations:

* The Photo could have a Key property (or ancestor) pointing to an
Album that does not exist

An inconsistent datastore is a problem with any framework - including Objectify. The trick is to use transactions where possible whenever working on an entity group to avoid getting this situation in the first place.

* The Album could have a List<Key> property, and some of the Keys
could point to Photos that do not exist


As above. An exception would be thrown saying which property on what object could not be found.

Maybe these are degenerate cases, maybe not, but you'll never be able
to completely avoid them.  RDBMSes have transactions and referential
integrity constraints that guarantee these later two cases can't
happen.  Not so in AppEngine.  You're just one
DatastoreTimeoutException away from having to deal with this situation
in your code.

If your data is inconsistent you have a problem - whether the framework throws an exception (as in Twig) or if you receive a null back from a finder method (as in Objectify) there is really not much difference. You still have to clean up the mess.

This is the big mess that makes JDO on Appengine so complicated,
possibly even more complicated than it is on an RDBMS.  On the other
hand... if you simply expose the Key (or OKey), the developer does a
little more work but doesn't have to figure out all the configuration.
Without proxies, all entities are serializable and GWT-able without
any special consideration.

I think that for simple cases and small data models working with Keys and handling the references yourself is fine. When things get more complicated it is easier to reconfigure how the data is actually stored if you can simply change a configuration option in one place.

Actualy, JDO doesn't even offer all the necessary configuration
options, which is probably why you end up seeing Key a lot as
properties in JDO sample code.

So.... while it seems like you might be able to keep Key and other
framework classes out of your entities... for many applications I
don't think it's realistic, and for most, I don't think it's a good
idea.

IMHO, of course.

Obviously we agree to disagree on this point :) I much prefer letting he framework handle repetitive boiler plate code with minimal configuration.

Another feature only supported by Twig is embedded collections - this allows
you to do a single query for Albums containing a particular photo for
example. In JDO, Objectify or any of the others this requires multiple
queries.  You configure it with a single Embed annotation like this:

We like this feature and are assimilating it now :-)

Nice one. It has honestly increased the performance of some queries by a factor of 10 at least.

Jeff

John

--
You received this message because you are subscribed to the Google Groups "Google 
App Engine for Java" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.

Reply via email to