Building a simple RIAK ORM

I’ve been interested in RIAK for a while, and ORM’s are nothing short of fascinating. I decided to try writing an ORM for Riak, and the results are here:

https://github.com/teverett/cbean

My ORM is not an ORM of course, because RIAK is not relational. However it is ORM-like; I can store POJO’s and retrieve them.

The features I wanted for my ORM were those that I am accustomed to with Hibernate, or eBean.

  • Ability to store POJO’s and retrieve them
  • Ability to store object trees of POJO’s which contain POJO’s
  • Support for Lists of POJO’s composed inside a POJO
  • Lazy Loading

In the end, I ended up with a ORM-like layer that can store data into any Key-Value store. There is a plugin which supports RIAK, and there is an emulated Key-Value store built on a filesystem, which is useful for development purposes. Theoretically cBean could work on any Key-Value store, such as MongoDB, but I haven’t built that support yet. Adding support for a Key-Value store is as simple as implementing the the interface KVService.

Supported Types

  • All java simple types (int, String, long, etc)
  • All java wrapper types (Integer, Long, etc)
  • Contained POJOs
  • java.util.List of POJOs
  • java.util.UUID
  • java.util.Date

Annotations

Similar to Hibernate or eBean, cBean POJO’s must be annotated. I didn’t chose to use the JPA annotations, but instead defined my own. They are here.  There numerous cBean annotated POJO’s in the tests, here.

@Entity

Similar to JPA, the @Entity annotation simply marks the POJO as one which is of interest to cBean.

@Id

Every POJO must have an id field and it must be a String or UUID.  The @Id field is a little different in cBean than in JPA.  Inserting a new object with the same JPA @Id as one that already exists in the RDBMS is an error.  In cBean, you simply overwrite the existing object.

@Property

The @Property is used to indicate that a specific property (simple type, wrapper type, object type or list type) will be persisted.  POJO fields without the @Property annotation are ignored.  There are a number of properties which are valid on an @Property annotation.

  • cascadeSave
  • cascadeDelete
  • cascadeLoad
  • ignore
  • nullable

cascadeSave, cascadeDelete, and cascadeDelete are only relevant for POJO fields which are themselves POJOs, or lists of POJOs.  Setting “cascadeLoad=false”, naturally, indicates that the field is lazy-loaded.

@Version

An POJO can define an Integer field and annotate it with @Version.  cBean will increment the annotated field by 1 each time the POJO is saved.

Referential Integrity

Frameworks like Hibernate or eBean provide referential integrity because RDBMS’s provide referential integrity.  Key-Value stores, such as RIAK do not provide referential integrity, and therefore neither does cBean.  Therefore is it entirely possible to persist a POJO which contains a POJO, and have the contained POJO be deleted underneath the parent.  In a RDBMS this can be prevented with a foreign key; there is no such protection in cBean.  Therefore application code using cBean must be aware that POJOs in lists, for example, may not be resolvable when the list is reloaded.

The strategy that cBean uses for handling broken “foreign keys” is two-fold:

  • If a POJO contains a child POJO and the child is deleted, that Object will be set to null on reload
  • If a POJO contains a list of POJO’s and one of the elements is deleted, the element Object will be set to null.  The List size() will remain the same as when it was persisted.

Example Code

There is a working example at https://github.com/teverett/cbean/tree/master/example.

Similar Posts

  • phpGrammar

    I’ve recently becoming interested in porting legacy PHP sites to JSPs.   It seemed to me that one of the hardest parts of this problem was parsing the PHP code.  Once a parse tree was created, the next step would be to emit equivalent JSP code. I went looking for an ANTL4 grammar for PHP,…

  • DOT4J

    I’ve recently been quite interested in Graph languages, not for Graph Databases, but for representing information, in code that is essentially “things” and “relationships”. For example, one perspective on Organizations is that they are simply representable as people, systems and the information that flows between them. Those three building blocks are, in theory, enough to…

  • Reading Paradox Files

    Back in the day, Paradox was a pretty amazing database.  I recently had a reason to read some Paradox files for a friend, who had a client with a Paradox database.  They needed their data out of the database to insert into something more modern. Googling for the file format of a Paradox DB didn’t…

  • MusicBrainzTagger

    I’ve tried a couple different mp3 taggers to tag my mp3 library, however, most seem to have trouble with large mp3 libraries.  So, after doing some reading about AcoustID and MusicBrainz I decided to quickly code up my own tagger, MusicBrainzTagger. MusicBrainzTagger is a command-line application which recurses a directory of mp3 files and tags…

  • |

    Embedding Jasper

    Jasper is the JSP compiler inside Tomcat. For reasons, mainly of curiosity, I wanted to build a Pragmatach plugin which exposes Jasper.  Pragmatach supports some template engines such as FreeMarker, ThymeLeaf and Velocity, but I thought Jasper would be a good addition. I chose to use Tomcat 6, mainly because Tomcat 7 uses Servlet 3.0.  Pragmatach…

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.