Freitag, 13. März 2015

In the last project where I had to use EclipseLink as the JPA provider for a web-based application. One of the nice features of EclipseLink is the ability of creating dynamic entities. Dynamic entities are virtual entities which can be mapped to the database. That means that you can define a entity at runtime and persist this entity. In this post I will show you how to create dynamic entities and what is needed to use this functionality in a Java EE application. At first you need to create an EntityManager for the defined persistence unit in your persistence.xml. After that you have to create a ClassLoader specifically for the dynamic entity classes by getting the Session and doing a lookup with that Session which returns the DynamicClassLoader. For creating the classes and mapping to the database you have to instantiate the JPADynamicHelper with the created EntityManager.
public void prepare() {
    entityManagerFactory = Persistence.createEntityManagerFactory("DefaultPU");
    entityManager = entityManagerFactory.createEntityManager();
    Session session = JpaHelper.getEntityManager(entityManager).getServerSession();
    dynamicClassLoader = DynamicClassLoader.lookup(session);
    jpaDynamicHelper = new JPADynamicHelper(entityManager);
}
Now you can create dynamically at runtime your first class with createDynamicClass from the DynamicClassLoader. This will return a new Java Class which you have to wrapp into a JPADynamicTypeBuilder. This class allows you to set the different fields and types of your entity and build in the end your dynamic entity class. After you defined your entity class your call addTypes from the JPADynamicHelper which than creates the table.
Class<?> dynamicEntityClass = dynamicClassLoader.createDynamicClass("org.demo.entity.DemoDynamicEntity");
JPADynamicTypeBuilder newType = new JPADynamicTypeBuilder(dynamicEntityClass, null, "DEMO_DYNAMIC_ENTITY");
newType.setPrimaryKeyFields("ID");
newType.addDirectMapping("name", String.class, "NAME");
newType.addDirectMapping("description", String.class, "DESCRIPTION");
jpaDynamicHelper.addTypes(true, true, newType.getType());
To instantiate and persist a dynamic entity you have to call newDynamicEntity from the JPADynamicHelper with the name of your defined class. This method will return you an object of type DynamicEntit which is a wrapper for your virtual classes. This class provides you setter and getter for the fields of your class. After you have finished setting the fields you can persist as usual by calling persist on the EntityManager.
DynamicEntity newDynamicEntity = jpaDynamicHelper.newDynamicEntity("org.demo.entity.DemoDynamicEntity");
newDynamicEntity.set("id", 1);
newDynamicEntity.set("name", "Demo");
newDynamicEntity.set("description", "Demo Entity");
entityManager.persist(newDynamicEntity);

2 Kommentare:

  1. Do you think this approach could be useful to add entities on the fly without using persistence.xml in an OSGi environment? I cannot use the Gemini JPA project as it does not support XA datasources for the time being.

    AntwortenLöschen