Handle multiple EntityManager in Java EE application

后端 未结 3 940
夕颜
夕颜 2020-12-19 10:29

I have Java EE application with about 10 EntityManagers (number of EMs will probably increase). My application also contains many stateless, statefull and message driven bea

3条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-19 11:23

    Composite persistence units - Java EE

    The way to handle multiple entity managers, i.e. multiple persistence units, in Java EE is to use composite persistence units (CPUs). Such a composite persistence unit can be assessed from one single point in the EE web-application, a datalayer. This needs to be a @Stateless EE bean though in order to work with the @PersistenceContext.

    Composite persistence units have been introduced to make possible reusing entity classes, among various Java applications. CPUs are a feature of Enterprise architecture. I choose to use EclipseLink as showcase, as I have positive experience with that from a running production application.

    Introduction

    In some cases, entities contain general data that is needed across more web-services in a server landscape. Take for example a general ‘name-address’ entity, a ‘user-password-role’ entity, a ‘document-keyword-index’ entity, etc. A composite persistence unit implementation facilitates that the source of each entity definition is specified in only one place (‘single point of definition’). These entity definitions can subsequently be included in each Java web-application that needs this entity access.

    Working of composite persistence unit

    The working of a composite persistence unit is illustrated by the following tutorial: EclipseLink composite persistence units

    The concept of composite persistence units works by first defining member persistence units. Each member persistence unit may be associated with a different database, but the member persistence units can also all refer to the same actual database. I have experience with the latter, where EclipseLink (version 2.6.4) was used in combination with one Postgress database.

    Maven is needed to make possible the required modular approach.

    Settings in persistence.xml

    A composite persistence unit member is defined as follows: Program a group of related entities (Java @Entity classes), one-by-one, in a dedicated Maven module. Define in this Maven module also a composite persistence unit member (important!). The composite unit member PuPersonData refers to this set of related entities that characterizes person data. Define the member persistence unit PuPersonData as (

    
    ...
        jdbc/PostgresDs
    ...
    

    ).

    In a second Maven module, define another composite persistence unit member, PuWebTraffic (

    
    ...
        jdbc/PostgresDs
    ...
    

    ). Include here other entities (Java classes denoted with @Entity) that store data about web-transactions, logon, sessions, etc. Needless to state, the two composite persistence unit members must be disjoint with respect to entities, no overlap is allowed in entity-names.

    Both persistence unit members have in their XML-definitions the property:

    
        
        ...
    
    

    Composite persistence unit

    We now define in a third Maven module the composite persistence unit CPuPersonSessionData that includes both the persistence units members PuPersonData and PuWebTraffic.

    
    

    This composite persistence unit CPuPersonSessionData refers to the two persistence unit members, PuPersonData and PuWebTraffic, by means of including the jars that result from compilation of the two pertaining Maven modules.

    ...
        PuPersonData.jar
        PuWebTraffic.jar
    ...
    

    In the XML-definition of the composite persistence unit, the following property needs to be set

    
        
        ...
    
    

    This setting ensures that the composite persistence unit is treated differently by Java EE than its persistence unit members.

    Use of persistence unit in Java

    In the Java web-application that is going to store and retrieve entities with both person-data and traffic-data, only the composite persistence unit is included

    @Stateless
    public class DataLayer {
    
        @PersistenceUnit(unitName="CPuPersonSessionData")
        EntityManager em; 
        ...
    

    The normal 'em' operations such as persist, find and merge can now be performed on each entity, contained in one of the composite entity members.

    Under Payara, no XA-transactions were needed for this composite persistence unit to address the entities pertaining to each of the persistence unit members.

    Maven

    The Maven parent POM file needs to contain the specifications for the pertaining modules.

    ...
        
                PersonData
                WebTraffic
                PersonSessionData
        
    ...
    

    The POM-file of each module needs to be configured as a normal Maven-project, referring to the parent POM-file.

    Pitfalls:

    • You need to configure the Maven multi-module project correctly, which can be somewhat tricky. Each composite persistence unit member constitutes a separate Maven module. Also the composite persistence unit is a separate Maven module. The members need to be compiled first, in Maven sequence.
    • The ‘jars’ in the composite persistence unit need to be found when compiling the module of the composite persistence unit.
    • The entities of each composite persistence unit member need to be available in the resulting ‘jar’, directly in the ‘classes’ directory (adding extra paths to the entities, via Maven, is possible but complex).
    • The ‘jars’ of the persistence unit members need to be available in the ‘classes’ directory for the composite persistence unit to find them.

    The benefit gained is a neat Enterprise data-layer that works with reusable entities, each with one central definition. Moreover, it is possible to perform cross-unit native SQL-queries. I got this to work also.

    Documentation states that cross-unit native queries will not work when the composite persistence unit members run on different, actual databases. This should still be verified.

提交回复
热议问题