metter metter - 23 days ago 6
Android Question

Couchbase lite on Android - General architecture?

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!

Answer

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.