Committed to Code

GAEDO stands for Google App Engine Data Object

It's a persistence project providing dynamic query code generation: you just need to define your interfaces!

For the moment Gaedo is compatible with the google appengine but is designed to be extended

This project is managed by Riduidel.

Project Tags Tagged as persistence appenginejava appengine dynamicprogramming

Code Analysis


Recent Highlights

Avatar

Large commit — implemented map persistence in graph !

More than 1000 lines of source code were added or removed in this commit.

In commit /p/gaedo/commits/177393894 by Riduidel (Using name ‘riduidel’) on 2012-05-07 (15 days ago)

See all highlights…


News

latest release is always here

I must say i'm a little tired of the crazy gaedo release train.

So, instead of writing a new blog entry each time, I will instead simply update this one.

So, for now, latest release of gaedo is <version>0.2.11</version>.


Puttin an end to the 0.2 release train

Today, the 0.2.9 release come to put an end to the 0.2 release train initiated by Gaedo is not dead, and the 0.2.0 release is done !.

I won't explain in details what it provide, suffice to say the last bugs fixable by 0.2.9 are fixed (or I ... [More] hope so). Please consider using it instead of previous versions as i will soon drop the repositories hosting them.

So update your poms and profit ! [Less]


Gaedo does graphs !

You now that gaedo does GAE persistence.

You now that gaedo also does prevalence persistence.

But did you know that gaedo does graph-backed persistence ?

Well, that's kind of normal, considering it does it only since ... [More] the 0.2.0 release.

Relying upon the excellent Tinkerpop blueprints library, we wrote adapted implementations that can be used to store/load/query beans in a graph DB, be it Neo4j, OrientDB, Tinkergraph, and all others (im|out)plementations of Blueprints IndexableGraph.

We must confess work on this is not yet over, as we somewhat want our persisted graph to be RDF-consistent (that's to say have all elements identifiable using URIs).

Nevertheless, this implementation is considered usable (and in fact already used).

But how do one use it ?

well, as usual, the tests are the answers.
Take a look, as an example, to GraphBackedPostFinderServiceTest. The @Before makes quite clear (to my mind) what one need to have a working graph-backked finder service :

        repository = new SimpleServiceRepository();
         PropertyProvider provider = new FieldBackedPropertyProvider();
         CumulativeFieldInformerLocator locator = new CumulativeFieldInformerLocator();
         locator.add(new BasicFieldInformerLocator());
         locator.add(new ServiceBackedFieldLocator(repository));
         ReflectionBackedInformerFactory reflectiveFactory = new ReflectionBackedInformerFactory(
                 locator, provider);
         InformerFactory proxyInformerFactory = new ProxyBackedInformerFactory(
                 reflectiveFactory);
         
         graph = graphProvider.get();
         // Now add some services
         repository.add(new BluePrintsBackedFinderService(Tag.class, TagInformer.class, proxyInformerFactory, repository, provider, graph));
         repository.add(new BluePrintsBackedFinderService(Post.class, PostInformer.class, proxyInformerFactory, repository, provider, graph));
         repository.add(new BluePrintsBackedFinderService(User.class, UserInformer.class, proxyInformerFactory, repository, provider, graph));
         tagService = repository.get(Tag.class);
         postService = repository.get(Post.class);
         userService = repository.get(User.class);

As usual, one need way to construct properties out of raw objects, then a persistent graph (obtained here throught the graphProvider.get() method which i'll explain later), a service repository and some service implementations. And that's all one need !

What will this create ? Well, you remember that previous blog post about bouncing query and the schema attached to it ? In fact, this schema was a screenshot of neoclipse (the Eclipse declinaison for neo4j visual exploration).

Finally, I would like to thank the blueprints ML, and even more particularly the people at neo4j. Indeed, when I did my first test (GraphBackedTagFinderServiceTest), I noticed strange performance patterns. As a consequence, I mailed the blueprints ML and had a very interesting mail discussion which Peter and Michael of Neo4j. it revealed the following point :

On my initial test performance of Neo4j was mainly affected by its startup time, which is indeed longer than both Tinkergraph and OrientDB one, mainly due to its enterprise-grade nature.
Those tests are in fact not really representative of long-term use, as I always stop my graph between each test, which is obviously not good.
More intensive performance test reveals in fact that node writing with auto-transaction mode lasts no longer than 2-5 ms per vertex write, which is perfectly supportable.

With all that said there is only one question remaining : what gaedo module contains all thise greatness ?

<dependency>
  <groupId>com.dooapp</groupId>
  <artifactId>gaedo-blueprints</artifactId>
  <version>0.2.0</version>
</dependency> [Less]


Gaedo is not dead, and the 0.2.0 release is done !

After a way too long sleep, the 0.2.0 release of gaedo should be available soon in a maven repository near you.

This release includes the following important elements :

issue: Bouncing queries do not work (already documented ... [More] in Gaedo bug in bouncing queries)
issue: Finalize the Spoon madness in a maven plugin (will be documented soon)
issue: Implement graph backed persistence (documented in Gaedo does graphs !).

So, what do you have to do ?
well, update your pom and profit ! [Less]


Gaedo bug in bouncing queries

I must confess something : I hate bugs. Really.
And I even more hate gaedo bugs : they are the living proof I'm not a perfect being.
And this bug (issue: Bouncing queries do not work) I have a specific hatred for.
Let me explain ... [More] it with a simple example (borrowed from gaedo-blueprints - more on that later - test) :

        @Test
        public void searchPostByAuthor() {
                int postsOf  = postService.find().matching(new QueryBuilder<PostInformer>() {
 
                        @Override
                        public QueryExpression createMatchingExpression(PostInformer informer) {
                                return informer.getAuthor().getLogin().equalsTo(USER_LOGIN);
                        }
                }).count();
                // All posts are from the same author
                assertThat(postsOf, Is.is(3));
        }

You see that request obtaining all posts from a user ? Well, it fails. Why ? Because we're looking up the Posts using a field from the User used as author.
Unfortunatly, up to now, FieldInformer (which is the base interface upon which all the query is built) had no information regarding the "properties path" used to access it from the query root. I don't know if I'm perfectly clear here, and I would like to clarify that claim using the attached schema.

So, you see, starting from any Post (say as an example com.dooapp.gaedo.test.Post:java.lang.Long:1 - that's a hell of an id, isn't it ?), looking up the user login require us to go the following route :

Post -> User -> login

Unfortunatly, QueryExpression had, up to now, no knowledge of that route, making that query totally impossible.
That's fortunatly no more the case, thanks to the addition of FieldInformerAPI, which is a derivation of fieldInformer all field informers (including Informer instances) should implement - don't worry, all those classes are gaedo one : your code won't change in any fashion.
This implies small architecture changes, but nothing you should be aware of.
And now, it will be possible to perform that query.

AttachmentSize

graph showing an example of failing query114.92 KB [Less]


Read all gaedo articles…

Edit RSS feeds.