Reputation: 189
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.
<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>
auth.User
is a technical entity that contains authentication-specific dataEntityManager
is created with Persistence API (since no injection is available for realms)META-INF/orm.xml
is used to define mappings (no @Entity
annotations at all)$GLASSFISH_HOME/glassfish/domains/domain1/lib
<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>
app.User
is a business entityEntityManager
is injected with @PersistenceContext@Entity
annotations (for basic mappings) and META-INF/orm.xml
file (for customization) are usedUpon 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
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):
<class-loader delegate="false"/>
in glassfish-web.xml
;META-INF/orm.xml
to something else and reflect it in persistence.xml
.Upvotes: 1
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