Hi: While exploring list-property and merge-join from this talk http://code.google.com/events/io/2009/sessions/BuildingScalableComplexApps.html i concur with your value proposition.
Initially, i plan to build a singleton long id generator to reproduce and self-manage datastore Key of the application entity graph. Then use the low-level datastore to create list-property and merge-join: User -> Message -> MessageIndex or User -> Activity -> ActivityIndex (of different properties such as Interest, Checkout, MesurableEvent, etc). Please: 1) Explain the difference from objectify-appengine with this simple- mind approach in the immediate and long term project. 2) It is excellent to show an example of both list-property and merge- join as well as best practices to leverage the zig-zag search of the app engine. 3) Configuration with appengine-java-sdk if there is any significant change beside a small jar from objectify-appengine. Thanks Duong BaTien DGBROUPS and BudhNet On Wed, 2010-01-20 at 23:45 -0800, Marcel Overdijk wrote: > This really looks great! > > On 13 jan, 18:28, Jeff Schnitzer <[email protected]> wrote: > > http://code.google.com/p/objectify-appengine/ > > > > I probably should have called this project "Goldilocks", because it's > > a little bit how I feel. Despite being a longtime Hibernate user > > (since the 1.0 days), the JDO/JPA abstraction just doesn't make me > > happy on appengine - it's too big, too complicated, and too far > > removed from the nature of the beast. The low-level API has an > > elegant simplicity, but it lacks type safety. I tried the > > alternatives - Siena, Twig, SimpleDS, and Slim3. There are good > > things I can say about these projects but none were "just right" for > > me. > > > > So, in time-honored tradition, I wrote my own and now I'm offering it > > to the world. Here is what "just right" means to me. Maybe it's just > > right for you too: > > > > * An interface that reflects the four fundamental datastore > > operations - get, put, delete, query - including their batch variants. > > > > * Persisting real typed POJO classes - no detaching, no lifecycle, > > serialize at will. > > > > * Keys inObjectifyare generified and typed. Instead of Key you use > > OKey<MyEntity>. This generic typing extends to OQuery<MyEntity> and > > OPreparedQuery<MyEntity>. > > > > * Because Kind ~= POJO Class, Key should not be used for an object's > > id. The object's id and its (optional) parent plus the class is > > complete; an entity that has a Key identifier contains a redundant > > (and potentially inaccurate) kind. Nevertheless, a Key is necessary > > for loading entities or referencing entities, and forms a fundamental > > part of the API. This dichotomy is something I don't feel had been > > done right yet. > > > > * Queries are modeled after the human-friendly GAE/Python Query > > class: query.filter("field >", 123).sort("-field"). You can filter > > and sort on id fields almost as if they are normal properties. > > > > * Transactional behavior is contained within theObjectifyinterface > > (analogous to DatastoreService) instance rather than a thread local. > > You can easily have several transactions (or nontransactional > > sessions) running concurrently. > > > > * You can use your entities in GWT-RPC without modification - even > > with OKey fields. They're just POJOs and they serialize fine. > > > > * Builtin facilities to help with renaming fields and transforming > > data during schema migration. > > > > * Configurable automatic retries for DatastoreTimeoutExceptions > > (finally get rid of the 0.1% trickle of failures!). > > > > * Zero external dependencies - no Spring, no Guice, not even a logger > > (it just wasn't necessary). Just one lonely 36K jar. > > > > *Objectifywill work nicely with your DI framework. Static > > singletons are not required. > > > > * Negligible impact on cold start time. > > > > * Thorough unit test suite. > > > > * Simple, easy-to-read, well-documented code. Not counting the > > tests, there's actually only ten source files plus three annotations. > > About 2,000 lines including whitespace and javadocs. > > > > There is ample documentation > > athttp://code.google.com/p/objectify-appengine/, but some code examples > > should make this clear: > > > > Basic operations: > > > > @Entity > > class Car { > > @Id String vin; // Can be Long, long, or String > > String color; > > Date registered; > > > > } > > > > Objectifyofy = ObjectifyService.begin(); > > ofy.put(new Car("123123", "red")); > > Car c = ofy.get(Car.class, "123123"); > > ofy.delete(c); > > > > OQuery<Car> query = ObjectifyService.newQuery(Car.class); > > query.filter("registered <", lastYear).sort("color"); > > List<Car> cars = ofy.prepare(query).asList(); > > > > Some more sophsticated examples: > > > > @Entity > > class Employee { > > @Id long id; // primitive long is never autogenerated > > @Parent OKey<Company> employer; > > > > // field getting renamed > > @OldName("boss") OKey<Employee> manager; > > > > String firstName; > > String lastName; > > > > // we used to store fullName, now we store first and last separately > > @OldName("fullName") public void oldWay(String fullName) > > { > > String[] split = fullName.split(" "); > > firstName = split[0]; > > lastName = split[1]; > > } > > > > } > > > > Here's an example of interleaving a transactional session with a > > nontransactional session: > > > > ObjectifyofyNoTxn = ObjectifyService.begin();ObjectifyofyTxn = > > ObjectifyService.beginTransaction(); > > try > > { > > Foo f = ofyTxn.get(Foo.class, "k123"); > > Bar b = ofyNoTxn.get(f.barKey); > > > > if (b.wantsUp()) > > f.increment(); > > else > > f.decrement(); > > > > ofyTxn.put(f); > > > > ofyTxn.getTxn().commit();} > > > > finally > > { > > if (ofy.getTxn().isActive()) > > ofy.getTxn().rollback(); > > > > } > > > > The full docs are here: > > > > http://code.google.com/p/objectify-appengine/ > > > > What doesn't it do? > > > > * It doesn't work with any datastore other than GAE. > > > > * It doesn't manage relationships for you - if you want cascading > > deletes, collection proxies, and all the advantages and disadvantages > > of that - you want JDO/JPA. I find managing this myself pretty easy, > > and well worth the transparency. > > > > * No support yet for polymorphism. It won't require major structural > > changes to add though. > > > > * It doesn't suck. Or so I am told. > > > > Jeff
-- 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.
