On 13 Mar 2010, at 11:00, Jeff Schnitzer wrote:

On Fri, Mar 12, 2010 at 4:26 PM, John Patterson <[email protected]> wrote:

It's hardly FUD to point out that every extra query counts.  In GAE,
you can measure the price (in $) of every single request.  In the
applications I have developed, it *matters* that you don't do multiple
queries to fetch excess data

The FUD I was referring to was you claim that uninitialised instances are magical. They are just normal instances with no values set. But I See below that you are coming to like the idea after all :)

For nontrivial applications, fetching a large object graph every time
you load an object just doesn't work.  This is why Hibernate added
proxies.  I'm glad you're sufficiently aware of this problem that
you're building in limits to activation, but I think you're nuts if
you think that these facilities will rarely be used.

I believe you claimed that Keys were not used all that often in Objectify. I guess that would also make you "nuts". Activation would be used less than Keys because it can be done as a part of optimisation when needed. I consider Objectifies use of Keys and manual loading of every relationship a "premature optimisation".


Proxies are a completely different beast. If bytecode manipulation were used there are suddenly serialization problems to worry about. That is why
Twig uses pure plain POJOs with NO magic.  As simple as possible.

Proxies serve the exact same purpose as your uninitialized entities.

They have the same purpose (with some advantages) but different implications and are more complex

They allow the fetch process to halt, because in nontrivial
applications you cannot afford to load large object graphs every time
you fetch a single entity.  As a solution, proxies have advantages and
disadvantages - just like your uninitialized entities have advantages
and disadvantages.

That is why, as the docs say, a future release will include an option to use proxies for automatic activation and dirty detection.

For now the simple "no magic" approach works fine and has less gotchas.

FWIW, I myself prefer the uninitialized entity solution over proxies,
despite the - quite significant - danger.  Just remember that if
everyone was using Twig instead of Hibernate, all those

After you explained the concept of uninitialized entities (the brief
blurb in your docs really isn't enough), I actually rather like your
solution!  I might even implement something similar in Objectify.

Thanks for the recognition! But I borrowed the concept from Db4o - just a shame that their implementation was completely useless for server apps (single threaded!).

Yes I admit that docs have so far come after features. Twig contains a hell of a lot of features to save developers time and make their code cleaner. Hopefully we'll get some other developers excited by these new features to join the effort to add documentation - and more features!! Automatic activation and dirty detection are high on the list of non-trivial additions.

 But I really think you need to document the hell out of the issues
surrounding them.  It is very very easy to corrupt data.


I think that it is easier to corrupt data in Objectify because the same instance can be loaded into memory more than once at the same time. Very easy to overwrite one with the other without realising. Twig guarantees that one entity will only have one instance in memory.

Sadly, this is where bytecode manipulation really would come in handy
- you can intercept data access on an uninitialized entity and throw
an exception.  It's too bad java dynamic proxies can't wrap concrete
classes.

Yes and too bad Guice's bytecode AOP doesn't support field access interceptors.

This is controllable in *very* fine detail by Activation settings. Any class can have a default activation depth, any field can have an activation depth and the datastore as a whole can set the depth for any individual operation. This gives *complete* control over what is loaded and when.

I wouldn't call it complete control.  It doesn't very gracefully
handle entities with multiple relationships - some queries you will
want to fetch some parts and not others.

Actually you can set activation per Class, Field or per datastore command. Also the ActivationStrategy makes it possible to make *any* control you can think of in Java code. But I don't think this will be hardly ever necessary.

However, the point is moot,
since you can (and IMNSHO probably should) always disable automatic
activation and refresh the graph manually.

Completely disagree. IMNSHO it i best to make the framework work out- of-the box first and optimize later. Although refreshing is handy you would end up in the same position as Objectify - all your code that uses your data models would need to reference the data layer (i.e. be ties to the platform)

Here's a bit of free advice:  You need a batch refresh() operation.

I feel privileged kind sir.  That is a very sensible feature request :)

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