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.