Saturday, August 05, 2006

Using a Domino Database to store Java Beans

Lotus Domino developers have long enjoyed the benefits of a flexible persistence layer that comes out of the box. The .nsf database, its surrounding APIs, full text indexer, and world class replication make it a very good candidate for creating a persistence layer for your java objects (java beans) across your company or enterprise. The purpose of this article is to demonstrate Lotus Domino's database flexibility with a thin data layer API that I decided to call Object Domino Map (ODM... very creative I know ;-). I was inspired to build ODM after working with a great open source tool called ibatis. I used ibatis to persist java objects to a relational database and thought that Domino's database would have a definite advantage in some ways over an RDBMS for storing objects.
One of the key factors of storing objects is Domino's database flexibility. Developers don't have to worry about mapping column names to java bean field attributes, nor do they have to be concerned about changing those attributes over time. Domino dynamically creates the fields for the developer as needed, and maintains any unused attribute in the document record. As the application's object model matures and the underlying java beans that persist the data change, the Domino database will keep everything including old attributes if needed. The rest of this article will focus on using the ODM API through setup and example.

What you need to get started:
  • Lotus Domino Server running DIIOP(free trial of the server at lotus)
  • Create an empty database on the root called books.nsf (FT Index the database)
  • A Java development environment setup
  • (latest version is in another post containing cache implementation)
    • Extract the .zip file and import the ODM.jar, source, and example code into a new project in your favorite IDE.
    • If you have any issues downloading please send me email (see end of article for address) and I will respond w/ .zip attachment.
  • Be sure to add NCSO.jar and the ODM.jar to your classpath/project libraries.
At the root of your source folder in the examples (default package) you should see two .properties files:, and Go into the file and alter the settings for your environment. Below are a listing of the properties and their descriptions:
    • Domino server that is hosting your database
    • username used to login to the server
    • password used to login to the server
    • number of sessions the DominoSessionFactory will produce
    • interval the sessions in the DominoSessionFactory are kept alive (calls isOnServer from Domino's session)
  • TARGET_DATABASE=books.nsf
    • nsf path used to store your java bean objects
    • a pointer to the properties file containing object/class specific settings (you must register each of your beans in the file)

class specific properties files (i.e.
  • objectNoteId=uniqueId
    • objectNoteId (required) is used to get a handle on the java bean using a pre-determined unique Id called noteId (note you can also use objectUNID to use the universal id across replicas).
  • onSave_dtModified=@Modified
    • onSave_attribute will evaluate a LotusDomino formula when the NEW object is saved to the database
  • onUpdate_dtModified=@Modified
    • onUpdate_attribute will evaluate a Lotus/Domino formula when a pre-existing object has been updated
  • onGet_dtCreated=@Created
    • onGet_attribute will evaluate a Lotus/Domino formula when the java bean object is retrieved.

Running the Example:
  • Go to the java class com.odmexample.CreateBooks and execute the file. This will create 100 objects (documents) in the book.nsf database using the attributes in the com.odmexamples.Book java bean as the field names.
  • Update the FT index manually (ODM supports both dbSearch, and FTSearch, but this example uses FT Index)
  • Go to another java class file com.odmexample.ViewBooksByAuthor and execute this file. It should print to the screen any authors with the name SpongeBob1 or the arg you specify (SpongeBob1, SpongeBob2 etc ;-).

Other features of ODM/Domino:
  • ODM supports the storage of primitive arrays like double, long, int and can also store arrays of strings.
  • ODM also supports the storage of any object attribute in your bean that implements serializable. The downside is that you can't search based on the object's info, and the serialized object cannot exceed 64kb.
  • File attachment support using saveWithFileAttachment option(attach any type of file to the object, file name and meta data should be stored w/ your bean attribute i.e. getFileName, getFileType...)
Possible Future Development:
  • Simple cache model of java beans and collections (will probably borrow from apache)
  • Instead of direct field access to the beans use method invoke reflection calls (since I'm violating rules of encapsulation ;-)
  • Review other means of processing beans without use of reflection, or one time reflection via code generation and compilation.
  • Change configuration files from .properties to xml (although I kind of like simplicity that property files bring)
  • Better logging (have LogUtils class (see source docs) but currently not using)

Lotus/Domino's datastore is one of the most flexible around and is fully owned and supported by IBM, making it a viable alternative to RDBMS for storing objects in most applications. The ODM API is available via the GNU General Public License. This is the first version of the API if you find any bugs or have questions please feel free to send me email(see my profile).