Martin Schmidt
Martin Schmidt

Reputation: 189

Hiding foreign entity classes from EclipseLink

I have a Java EE web application and a custom realm (authentication module) for Glassfish 4 (see GlassFish Application Development Guide, II 4-6 "Creating a Custom Realm"). Both of them are using JPA, with subtle differences.

Custom realm

<persistence-unit name="AuthPU" transaction-type="JTA">
    <jta-data-source>jdbc/AuthDB</jta-data-source>
    <class>auth.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>

Application

<persistence-unit name="AppPU" transaction-type="JTA">
    <jta-data-source>jdbc/AppDB</jta-data-source>
    <class>app.User</class>
    <exclude-unlisted-classes>true</exclude-unlisted-classes>
</persistence-unit>

Upon application deployment, an exception is thrown:

Severe:   javax.persistence.PersistenceException: Exception [EclipseLink-28018] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.EntityManagerSetupException
Exception Description: Predeployment of PersistenceUnit [AppPU] failed.
Internal Exception: Exception [EclipseLink-7237] (Eclipse Persistence Services - 2.6.0.v20150309-bf26070): org.eclipse.persistence.exceptions.ValidationException
Exception Description: Entity name must be unique in a persistence unit. Entity name [User] is used for the entity classes [app.User] and [auth.User].

Seems like AppPU persistence unit somehow discovers entities from auth.* package (via orm.xml?) I don't want to alter entity names because it will break existing JPQL queries. How can I isolate the modules so that AppPU ignores foreign orm.xml and doesn't look into auth.* package for entities?

P.S. As you may have noticed, EclipseLink version is 2.6.0 - I've upgraded it manually. Eclipse 2.5.2 shipped with GlassFish 4.1 gave the same exception.

Upvotes: 0

Views: 397

Answers (2)

Martin Schmidt
Martin Schmidt

Reputation: 189

Okay, I've figured out what exactly happens.

According to GlassFish Application Deployment Guide (C-13),

the web module follows the standard class loader delegation model and delegates to its parent class loader first before looking in the local class loader.

This is the default behavior which can be controlled with <class-loader> element of glassfish-web.xml. EclipseLink tries to process each and every META-INF/orm.xml it finds on classpath, and thus, picks that of the custom realm first. Even if application's orm.xml contains <xml-mapping-metadata-complete/>, it doesn't play a role, as auth.* classes are already added to the persistence unit.

There are two solutions for the problem (beside renaming entities):

  1. Use <class-loader delegate="false"/> in glassfish-web.xml;
  2. if the above is not acceptable ("for a web module that accesses EJB components or that acts as a web service client or endpoint" - Application Deployment Guide), rename custom realm's META-INF/orm.xml to something else and reflect it in persistence.xml.

Upvotes: 1

Alan Hay
Alan Hay

Reputation: 23246

From the book Pro JPA2

xml-mapping-metadata-complete

When the xml-mapping-metadata-complete element is specified, all annotations in the entire persistence unit will be ignored, and only the mapping files in the persistence unit will be considered as the total set of provided metadata. Only entities, mapped superclasses, and embedded objects that have entries in a mapping file will be added to the persistence unit. .....

<entity-mappings> 
    <persistence-unit-metadata>
         <xml-mapping-metadata-complete/> 
    </persistence-unit-metadata> ...
</entity-mappings> 

Add the above to your orm.xml.

Upvotes: 0

Related Questions