Sunday, September 23, 2012

Mardao 2 is released


I am very pleased to announce the first release of Mardao 2! The following requirements have been considered when rewriting from scratch:
  • Domain objects are now true POJOs with Annotations - no need to extend a class or implement an interface
  • Application code and generated code are completely agnostic of persistence type
  • @CreatedBy and @UpdatedBy are new auto-populated fields
  • @GeoLocation supports creating geo-hashes to do nearby and spatial searches
  • Domain fields can be of basically any field
  • Support for transient fields - by omitting @Basic annotation
  • All non-unique queries return an Iterable or a page
  • Support for cursors and cursor keys
  • Generator uses reflection to scan objects
  • True separation between generic Dao functionality, persistence-specific code and domain-specific methods

Example apps in production using Mardao

The following apps or services are in production and are using mardao:
  • Heathrow Airport Guide (Backend / Google App Engine)
  • TwoForOne voucher app (Android application / SQLite)
  • European Directories Mobile (XHTML web app / Spring JDBC / MySQL)
  • SonyEricsson Update Service (Backend / Spring JDBC / Oracle)
  • Golden Gekko device detection service (Backend / Google App Engine)
  • Google Search Prototype (BlackBerry / SQLite)

Read more at the mardao wiki on GitHub: https://github.com/sosandstrom/mardao/wiki

Tuesday, March 27, 2012

Spring Social on Google AppEngine

If you run into the 
javax.net.ssl.HttpsURLConnection is a restricted class
issues using Spring Social on Google AppEngine, please note that ClientHttpRequestFactorySelector 
"Picks a HttpComponentsClientRequestFactory factory if Apache HttpComponents HttpClient is in the classpath. If not, falls back to SimpleClientHttpRequestFactory."


So check your classpath! Avoid HttpClient on AppEngine!

Monday, February 27, 2012

Storing Documents in AppEngine's Datastore

Storing Documents in AppEngine's Datastore

One of the advantages of Google AppEngine's Datastore is that it is schema-less. You can simply store any Entity you wish, as long as you abide the indexes.
In this post, I will mimic the MongoDB document store, where you can store any kind of JSON document in your collection, as long as it has attributes for your collection's indexes.

Objectives

  • I would like to access the document store using a generic REST-JSON API, which implements basic CRUD methods plus a query method
  • On the consumer side, I  would like to map to POJOs, not a map
  • I would like to be able to store new kinds of objects without interrupting the service
  • I would like to be able to introduce new attributes on my entities without updating any of the existing entities

Source for the json-doc-store

The source code is hosted on BitBucket.
hg clone https://bitbucket.org/f94os/json-doc-store

Binding request from JSON to Map

The intermediate data type when using Spring and jackson JSON mapper is the Map class:
    @RequestMapping(value="{kind}", method= RequestMethod.POST)
    public ResponseEntity createDocument(
            @PathVariable String kind,
            @RequestParam String id,
            @RequestBody Map props
            ) { 
      // Spring and Jackson binds my JSON object to a Map 
// Bind to AppEngine Datastore Entities // persist in datastore }

Read a document from the datastore

The Spring Controller method to create entities looks like this:
Create by kind only (generate key)
    @RequestMapping(value="{kind}/{id}", method= RequestMethod.GET)
    public ResponseEntity> getDocument(
            @PathVariable String kind,
            @PathVariable Object id
            ) {
        
        // query for ancestors, including ancestor

        // bind from Entities to Map
 
        // Jackson will serialize from Map to JSON 
     }

Namespace and Kind

A relational database can be compared to using Namespaces in the Datastore, and a table can be compared to using the Entity Kind.

Admin database

MySQL uses a database with tables for users, user databases, user tables and so on. The same concept is done here, with an admin Namespace of json-doc-store, and two Kinds, _DBs and _Users.