Registering entity types with OpenJPA programmatically

I’ve just started work on an OpenJPA objectstore for Isis. In the normal scheme of things, one would register the entity types within the persistence.xml file. However, Isis is a framework that builds its own metamodel, and can figure out for itself which classes constitute entities. I therefore didn’t want to have to force the developer to repeat themselves, so the puzzle became how to register the entity types programmatically within the Isis code.

It turns out to be pretty simple, if a little ugly. OpenJPA allows implementations of certain key components to be defined programmatically; these are specified in a properties map that is then passed through to javax.persistence.Persistence.createEntityManager(null, props). But it also supports a syntax that can be used to initialize those components through setter injection.

In my case the component of interest is the openjpa.MetaDataFactory. At one point I thought I’d be writing my own implementation; but it turns out that the standard implementation does what I need, because it allows the types to be injected through its setTypes(List<String>) mutator. The list of strings is passed into that property as a ;-delimited list.

So, here’s what I’ve ended up with:

final Map<String, String> props = Maps.newHashMap();

final String typeList = entityTypeList();
props.put("openjpa.MetaDataFactory",
  "org.apache.openjpa.persistence.jdbc.PersistenceMappingFactory(types=" + typeList + ")");

// ... then add in regular properties such as 
// openjpa.ConnectionURL, openjpa.ConnectionDriverName etc...
            
entityManagerFactory = Persistence.createEntityManagerFactory(null, props);

where entityTypeList() in my case looks something like:

private String entityTypeList() {
    final StringBuilder buf = new StringBuilder();
    // loop thru Isis' metamodel looking for types that have been annotated using @Entity
    final Collection<ObjectSpecification> allSpecifications = 
        getSpecificationLoader().allSpecifications();
    for(ObjectSpecification objSpec: allSpecifications) {
        if(objSpec.containsFacet(JpaEntityFacet.class)) {
            final String fqcn = objSpec.getFullIdentifier();
            buf.append(fqcn).append(";");
        }
    }
    final String typeList = buf.toString();
    return typeList;
}

Comments welcome, as ever.

About these ads

Posted on May 30, 2012, in Uncategorized and tagged , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 248 other followers