Adding entity classes dynamically at runtime

JPA doesn’t offer this feature yet. Here are three options you can check out :

  • This work around :
    1. Generate a persistence.xml on the fly (simple XML file creation) with a new persistence unit.
    2. Add persistence file to classpath dynamically (URLCLassLoader)
    3. Ask PersistenceProvider to load new persistence unit (createEntityManagerFactory)

I did implement this workaround. However, it didn’t scale well as the number of entities grows (100+). I finally switched to JDBC. Here is a capture of the memory consumption (-75%) before and after the switch from JPA to JDBC.

Memory consumption reduction by switching from JPA to JDBC

Nota

If the JPA provider is Hibernate, since Hibernate 4.0, it’s possible to pass directly entities to this JPA provider without declaring them in the persistence.xml file. Hibernate will handle the entities on the fly.

Here is a sample configuration of JPA 2.1 + Hibernate 4.3.7.Final without declaring any entities :

META-INF/persistence.xml

<?xml version="1.0" encoding="UTF-8" ?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
    version="2.1">

    <persistence-unit name="my-persistence-unit"
        transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <!-- Database Properties -->
            <property name="javax.persistence.jdbc.url"
                value="jdbc:postgresql://localhost:5432/my-database" />
            <property name="javax.persistence.jdbc.user" value="login" />
            <property name="javax.persistence.jdbc.password" value="password" />

            <!-- Hibernate Properties -->
            <property name="hibernate.connection.driver_class" value="org.postgresql.Driver" />
            <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
            <property name="hibernate.default_schema" value="public" />
            <property name="hibernate.hbm2ddl.auto" value="update" />
            <property name="hibernate.show_sql" value="false" />
            <property name="hibernate.format_sql" value="true" />

            <!-- Connection Pool -->
            <property name="hibernate.c3p0.min_size" value="5" />
            <property name="hibernate.c3p0.max_size" value="20" />
            <property name="hibernate.c3p0.timeout" value="500" />
            <property name="hibernate.c3p0.max_statements" value="50" />
            <property name="hibernate.c3p0.idle_test_period" value="2000" />
        </properties>
    </persistence-unit>

</persistence>

References

Leave a Comment