James Williams
LinkedInMastodonGithub

Carbonado and Griffon

As it stands now, Griffon doesn't yet support GORM. In pre-Griffon apps, I got around this by using Groovy's SQL datasets and some light raw SQL. Since Griffon is all about simplification, I decided to see if any object-relational mappers work with little modification. Carbonado is one that does.

Carbonado is a Java ORM, initially developed by Amazon that is now an Apache project. It has much of the stardard ORM fare but also supports Berkeley DB. One of the reasons I chose it for this small scall demo was the fact that it doesn't require configuration files. Domain objects are annotated interfaces whose concrete implementations are generated at run-time. Very Groovy-like.

Here's my StoredMessage domain object:

import com.amazon.carbonado.PrimaryKey;
import com.amazon.carbonado.Storable;
@PrimaryKey("ID")
public interface StoredMessage extends Storable {
    long getID();
    void setID(long id);
    String getMessage();
    void setMessage(String message);
}

Coming back to the Griffon structure for a moment, StoredMessage.groovy found its home in /src/main/groovy.

The model for this example is very short with only a String property:

import groovy.beans.Bindable

class CarbonadoDemoModel {
    @Bindable message
}

The view is equally brief, changing the label to be bound the model:

application(title:'CarbonadoDemo',  size:[150,75], 
   location:[50,50], locationByPlatform:true) {
    label(text:bind(source:model, sourceProperty:'message')) 
}

Startup.groovy is where the real heavy lifting is done(ie loading the repository, writing/reading from it, and binding to the model).

import java.io.File;
import com.amazon.carbonado.Repository;
import com.amazon.carbonado.RepositoryException;
import com.amazon.carbonado.Storage;
import org.apache.derby.jdbc.EmbeddedDataSource

import com.amazon.carbonado.repo.sleepycat.BDBRepositoryBuilder

def rootModel = app.models.root  

try {
    // Need to build access to a Repository instance. In this
    // case, we're building access to a Repository that stores
    // data in Berkeley DB.
    BDBRepositoryBuilder builder = new BDBRepositoryBuilder();
    // All Repositories require a name to be configured.
    builder.setProduct("JE");
    builder.setName("test");
    builder.setEnvironmentHome("testRepo");
    builder.setTransactionWriteNoSync(true);

    // Now build the Repository instance.
    Repository repo = builder.build();
    // Access Storage for a specific type of Storable.
    Storage<storedmessage> storage = repo.storageFor(StoredMessage.class);
        /*        
        //Insert message.
            StoredMessage message = storage.prepare();
        message.setID(1);
            message.setMessage("Hello Carbonado!")
            message.insert()
        */
        // Get message from repository  
        StoredMessage message = storage.prepare();
        message.setID(1);
        message.load()
        rootModel.message = message.getMessage()
} catch (Exception e) {
    e.printStackTrace()
}

Until GORM is there, Carbonado seems like a good solution for small to medium scale applications that are too big to do raw SQL and too small to deal with the multiple config files Hibernate needs.

Download the source here.