Skip to content
nocquidant edited this page Oct 28, 2011 · 33 revisions

Welcome

Welcome to Jenmo, a Java project built on top of JPA. It is an implementation of a graph-oriented domain model in order to benefit the advantages of a unified schema in relational database. It is available under the terms of the Apache Software License.

The name Jenmo results from the contraction of two words: Gen-eric and Mo-del (‘J’ is for Java). It is a project made of about 80 classes and 5000 lines of code.

Generic Schema

Over the 80 project classes, only 9 have a correspondence in datastore: they form the graph-oriented domain model and the generic shema.

Figure 1 : the graph-oriented domain model

In substance, graph vertices are modelized by Node entities, and graph links by Edge entities. Note that this is a directed graph i.e. edges have orientation.
A Node holds values with NodeProperty and NodeField entities depending of the nature of the property values.
A Node is described by metadata modelized by NodeType and Property.

Below is a very simple code example:


// Create Metadata (UserConstants is enum)
Property login = Property.newInstance(UserConstants.LOGIN.name());
Property email = Property.newInstance(UserConstants.EMAIL.name());
Property account = Property.newInstance(UserConstants.ACCOUNT.name());
NodeType typeUser = NodeType.newInstance(TypeConstants.USER.name(), login, email, account);

// Create Node user
Node aUser = Node.newRoot(typeUser, "aUser");

// Set property values to user
aUser.setProperty(login, "aUserLogin");
aUser.setProperty(email, "aUser@company.com");

// Create Node child
Node aUserChild = Node.newOutput(aUser, typeUser, "aUserChild");

// Set property values to child (simple ones)
aUserChild.setProperty(login, "aUserChildLogin");
aUserChild.setProperty(email, "aUserChild@company.com");

// Set property values to child (complex ones)
Map<String, BigDecimal> accounts = aUserChild.getProperties(account, 
      Descriptors.mapForProps(String.class, BigDecimal.class));
accounts.put("bnp", new BigDecimal(75000.98));
accounts.put("lpb", new BigDecimal(25022.25));

// Persist: note that we only need to explicitly persist a single root of the
// object graph, since we have the "cascade" annotation on all the relations
em.persist(aUser);

// Commit the transaction, which will cause the entity to
// be stored in the database
em.getTransaction().commit();

The main purpose with Jenmo was to achieve a unified schema in database. Key points of a unified schema are (non exhaustive list): avoid complicated SQL migration scripts after changes in the domain-model, facilitate the use of an ETL if needed, make easier exports of domain-model sub parts either with SQL scripts or in Java, facilitate Node deletion in database…

Functionalities

The Jenmo main functionalities are listed below:

  • cache system using SoftReference
  • extensible configuration system
  • localised messages and exceptions
  • JPA EntityManager lifecycle management (session-per-thread model or not)
  • generic DAO to provide specific data-access operations
  • generic Adapters to convert Node relationships into interfaces expected by client code
  • splitted blobs in datastore with the opportunity to extract sub-parts only
  • listener system to listen for blob extractions from datastore
  • simple API for manipulations of multidimensional arrays

News

Jenmo 0.9.2 released!

Resources

Limitations

At the moment, Jenmo has been used with MySQL 5.0, PostgreSQL 8.3, OpenJPA 2.0 and EclipseLink 2.0.0. Tests should begin shortly with Hibernate