Sounds like exactly what i was looking for!

Cant wait to try it

thanks, erik

On 13 Jan., 18:28, Jeff Schnitzer <j...@infohazard.org> 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 in Objectify are 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 the Objectify interface
> (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.
>
>  * Objectify will 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;
>
> }
>
> Objectify ofy = 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:
>
> Objectify ofyNoTxn = ObjectifyService.begin();
> Objectify ofyTxn = 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 google-appengine-j...@googlegroups.com.
To unsubscribe from this group, send email to 
google-appengine-java+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.


Reply via email to