Search code examples
mysqljpajakarta-eeeclipselinkpersistence.xml

Composite Persistence Unit using a single JAR file


I have searched the web and this site already for an answer. Although I found one link through a Google search, I subsequently lost the link and can't find it again.

I have been working on an e-commerce web site running on Glassfish 4.1.1 that originally had a single database (DB) using EclipseLink 2.6.4, but it now requires three that will reside on multiple servers (in order to keep customer data secure). The site worked fine with the single DB. I split the data from the single DB into three. The entities and JPA controllers defined in the J2EE code are all the same (I preserved the code so I wouldn't have to rewrite everything, only make minor changes such as annotations, etc.), but they are now located in three different MySQL databases. The three databases have relationships to one another.

In theory (and according the the link I saw and lost) a composite persistence unit (PU) can be defined to incorporate all three PU's for the three different data sources all within a single JAR file and using tags for the entity-PU mappings. Most of the examples (and the Eclipselink and Oracle Persistence API documentation) use a Composite PU with multiple JAR files (e.g.: https://github.com/forgemo/eclipselink-composite-persistence-unit-example).

Can anyone point me in the right direction as to how to create a composite PU without having to use a separate JAR file for each database PU?

My current persistence.xml file (musltiple PUs but not a composite) is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1" 
             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"
>

<persistence-unit name="PU1" transaction-type="JTA">
    <jta-data-source>java:app/jdbc/db1</jta-data-source>
    <class>com.mysite.myproject.Database.Items</class>
    <class>com.mysite.myproject.Database.Manufacturer</class>
    <class>com.mysite.myproject.Database.Category</class>
    <class>com.mysite.myproject.Database.Cart</class>
    <class>com.mysite.myproject.Database.AuditTable</class>
    <class>com.mysite.myproject.Database.Images</class>
    <class>com.mysite.myproject.Database.Procedures</class>
    <class>com.mysite.myproject.Database.Warehouse</class>
    <class>com.mysite.myproject.Database.Wishlist</class>
    <class>com.mysite.myproject.Database.Purchases</class>
    <class>com.mysite.myproject.Database.TaxTables</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
        <property name="eclipselink.logging.level" value="FINE"/>
    </properties>
</persistence-unit>

<persistence-unit name="PU2" transaction-type="JTA">
    <jta-data-source>java:app/jdbc/db2</jta-data-source>
    <class>com.mysite.myproject.Database.AccessList</class>
    <class>com.mysite.myproject.Database.Users</class>
    <class>com.mysite.myproject.Database.Customer</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
        <property name="eclipselink.logging.level" value="FINE"/>
    </properties>
</persistence-unit>

<persistence-unit name="PU3" transaction-type="JTA">
    <jta-data-source>java:app/jdbc/db3</jta-data-source>
    <class>com.mysite.myproject.Database.Key1</class>
    <class>com.mysite.myproject.Database.Key2</class>
    <class>com.mysite.myproject.Database.Key3</class>
    <class>com.mysite.myproject.Database.Key4</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
    <properties>
        <property name="javax.persistence.schema-generation.database.action" value="create"/>
        <property name="eclipselink.logging.level" value="FINE"/>
    </properties>
</persistence-unit>

The above persistence.xml works fine as long as there are no relationships between data sources (e.g. - relationship between Wishlist and Customer tables results in "[class com.mysite.myproject.Database.Wishlist] uses a non-entity [class com.mysite.myproject.Database.Customer] as target entity in the relationship attribute [field customer]" at deployment).


Solution

  • As it turns out, it seems a composite persistence unit is not needed (which probably explains why nobody can answer the question and there is little documentation about them).

    After finding many, many bugs in Glassfish, Geronimo, WebLogic, and Ecplipselink, and NetBeans, I was finally able to get the system working using multiple persistence units (PU) without using a composite PU. JTA is able to persist all entities including their references to entities outside their own PU. One key factor to making this work is to make sure classes not part of a PU are NOT excluded by adding this to your PU definition in persistence.xml:

    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    

    as in the following complete PU example (one of the three I use in my project):

    <persistence-unit name="DHWPU" transaction-type="JTA">
        <jta-data-source>jdbc/dhw</jta-data-source>
        <class>Database.AuditTable</class>
        <class>Database.Cart</class>
        <class>Database.Category</class>
        <class>Database.Images</class>
        <class>Database.Items</class>
        <class>Database.Manufacturer</class>
        <class>Database.Procedures</class>
        <class>Database.Purchases</class>
        <class>Database.TaxTables</class>
        <class>Database.Warehouse</class>
        <class>Database.Wishlist</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
    
        <properties>
            <property name="javax.persistence.schema-generation.database.action" value="none"/>
            <property name="eclipselink.logging.level" value="FINE"/>
        </properties>
    </persistence-unit>