Registering entity types with OpenJPA programmatically
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
Reference: Registering entity types with OpenJPA programmatically from our JCG partner Dan Haywood at the Dan Haywood blog blog.