6

We are building a project using couchbase. On Android, I use couchbase lite. Usually, I've been working with relational databases and because I am new to couchbase I am having trouble finding the "correct" architecture. I do understand the core concepts I think, but all the samples and guides seem to stick to some kind of easy setup where they access the database right in the Activities.

I am more used to having some database abstraction where the business logic only get's to see POJO DTO's that are delivered through a database interface or some DAO or something. So I've now annotated my model classes and started writing a simple OR mapper, but with different types of data, foreign keys etc. this is getting quite time consuming quite fast.

Am I completely missing the point here somehow? I can't imagine everyone doing it this way? I everyone writing methods that convert Documents to POJO model classes for each class seperately? Or using a json parser to do that (But that won't work for foreign keys if I wan't to load them too, does it)?

Sorry for the load of questions, but I feel I am missing something obvious here. Thanks!

metter
  • 1,434
  • 11
  • 22

1 Answers1

5

Will try answering your questions:

Am I completely missing the point here somehow?

No. You can treat noSQL CB as a persistent distributed object cache. So its not RDBMS. However, DAO pattern perfectly fits into this model...since you are dealing with DTOs/ValueObjects/POJOs on DAO level and on noSQL level.

I can't imagine everyone doing it this way?

I suggest write one universal Couchbase manager class that can persist/retrieve a POJO. Then you can re-use it in your DAOs.

Everyone writing methods that convert Documents to POJO model classes for each class separately? Or using a json parser to do that (But that won't work for foreign keys if I wan't to load them too, does it)?

You can have one common code in your Couchbase manager class that does conversion from/to json to POJO. So you work with only POJOs and don't see any json in your application code (outside of Couchbase manager class) Here is an example of such class:

public class CouchbaseManager<K, V>
{
  private final Class<V> valueTypeParameterClass;

  @Inject
  private CouchbaseClient cbClient;

  @Inject
  private Gson gson;

  public CouchbaseManager(final Class<V> valueClass)
  {
    this.valueTypeParameterClass = valueClass;
  }

  public V get(K key)
  {
    V res = null;
    String jsonValue = null;
    if (key != null)
    {
      jsonValue = (String) cbClient.get(key);
      if (jsonValue != null)
      {
        res = gson.fromJson(jsonValue, valueTypeParameterClass);
      }
    }
    return res;
  }

  public void put(K key, V value)
  {
    int ttl = 0;
    cbClient.set(key, ttl, gson.toJson(value, valueTypeParameterClass));
  }
}

Then in your DAO code you create instance of CouchbaseManager for each type:

CouchbaseManager<String,Customer> cbmCustomer = new CouchbaseManager<String,Customer>(Customer.class);

CouchbaseManager<String,Account> cbmAccount = new CouchbaseManager<String,Account>(Account.class);

// and so on for other POJOs you have.
// then get/put operations look simple
Customer cust = cbmCustomer.get("cust-1234");
cust.setName("New Name"); // mutate value
// store changes
cbmCustomer.put(cust.getId(), cust);

Now regarding "foreign keys". Remember its not RDBMS so its up to your code to have notion of a "foreign key". For example a Customer class can have an id of an account:

Customer cust = cbmCustomer.get("cust-1234");
String accId = cust.getAccountId();
//You can load account
Account acc = cbmAccount.get(accId);

So as you can see you are doing it all yourself. I wish it was JPA or JDO implementation/provider for Couchbase (like DataNucleus or Hibernate)

You should really start with your POJO/Document design to try to split your POJO entities into "chunks" of data to get a right balance between coarse vs fine grained POJOs. Also see this discussion on key/document design considerations.

Community
  • 1
  • 1
user1697575
  • 2,830
  • 1
  • 24
  • 37
  • Thanks for your insight! I've come to the same conclusion at work today and ended up writing my own OR mapper. To keep it generic and to support relations between documents, I'm now using annotations and check them by reflection. So far, this approach seems to work as intended. I'm still a bit baffled however that I had to do that as I imagine that most projects would need something like this in some form or another. Anyhow, thank you! – metter Sep 18 '14 at 16:30
  • @metter Have you found any other options for using POJOs with Couchbase Lite? If you decided to move forward with your own generic implementation, do you plan to open source it? I'm especially interested in an annotation based approach with support for relations as you mentioned. – ashughes Feb 25 '15 at 07:31
  • @ashughes Yes, I did end up using my own. However, it is in no way in a state that would allow me to open source it and I am working on another project now. – metter Feb 26 '15 at 07:32
  • Excuse my ignorance, but what is CacheMan? – 1vand1ng0 Nov 14 '16 at 22:10
  • 1
    @1vand1ng0 Good catch! You should read it as cbClient. I've also updated my code example. – user1697575 Nov 16 '16 at 17:34