CRUD with Terrastore

Mats Henricson

Crisp AB

Why NoSQL?


NoSQL is interesting if you value:

Agile methods?


Who enjoys writing DAO classes?

Is it possible to not having to write tedious DAO classes with a NoSQL database?

The first NoSQL database I looked at was Cassandra.
How do you do CRUD with Cassandra?

Java API:s for Cassandra


For Scala:

Real example from the Scromium docs



ks.insert("its", "a" -> "stack" -> "of", "fuckshit")

Well... perhaps I should pick another API?

Pelops, Cassandra's beautiful son


There's almost no documentation...

How beautiful is that?

Hector


Pretty good documentation, but unfortunately very low level.

To persist your POJO:s you'll have to write your own DAO classes,
by hand, much like you did with JDBC.

How agile is that? Answer: Not at all!

Perhaps a document database?


From NoSQL conference in London in April:

"Which NoSQL database should you choose?
Use a document database if you can get away with it."

NoSQL document databases




It turns out Terrastore has a very elegant Java API,
written by a Swede, Sven Johansson!

Terrastore!


Other features


Future releases


So, what is a document?


For our purposes

Terrastore guarantees to always give you the latest version of a single document!

Example


  public class Teacher {
    private String name;
    // ...
  }

  public class Student {
    private String name;
    // ...
  }

  public class Course {
    private String name;
    private Teacher teacher;
    private List<Student> students;
    // ...
  }

Example problem


  public class Student {
    private String name;
    private List<Course> courses;  // Would not work !!

    // ...
  }

  public class Course {
    private String name;
    private Teacher teacher;
    private List<Student> students;
    // ...
  }

A Jackson bug prevents us from having cyclic references,
so beware!

Smallish clusters of POJO:s?


You store your domain objects into different buckets. Exemples:
If you need to link objects in different buckets,
then you have to use domain unique IDs.

Annotations? Base classes?



Nope. The POJO:s are plain vanilla vanilla POJO:s.

Buckets?


Yes, buckets.

One bucket for customer data.
One bucket for items.
One bucket for orders.

Buckets are identified by string names,
such as "customers", "items", "orders".

Buckets are comparable to RDBMS tables,
but with no schema!

Enough! I want an example, now!


First we need a terrastore client

  TerrastoreClient client =
    new TerrastoreClient("http://localhost:8080",
                         new HTTPConnectionFactory());

That localhost URL points to a terrastore server.
If that server goes down, then your client is toast.
Future versions of the API will implement fallbacks.

Now lets create the POJO:s



  Student plato = new Student("Plato");
  Student camus = new Student("Camus");
  Teacher socrates = new Teacher("Socrates");
  Course philosophy = new Course("Philosophy");

  // Set relationships
  philosophy.setTeacher(socrates);
  philosophy.addStudent(plato);
  philosophy.addStudent(camus);

Create, Read and Delete


  BucketOperation courses = client.bucket("courses");

  // Create:
  courses.key("philosophy").put(philosophy);

  // Read:
  Course p = courses.key("philosophy").get(Course.class);
  // Important: p != philosophy

  // Delete:
  courses.key("philosophy").remove();

You can update a document with another put()

So, are we done?


No, there is a lot more cool stuff!

XPath!



  String xpath = "jxpath:/teacher/name[.='Socrates']";

  Map<String, Course> philosophyCourses =
    coursesBucket.predicate(xpath).get(Course.class);

  assertTrue(philosophyCourses.containsValue(philosophy));

Internally using JXPath.