Warn user when multiple persistence-units use the same name

Description

The JPA spec states that persistence-unit names should be unique. If this is violated we currently simply ignore it and return the last one we find ("last one" being non-deterministic based on CL). Change that to warn the user when this condition is recognized.


Original Description


Our project has two persistence.xml files:

  • core/target/test-classes/META-INF/persistence.xml

  • core/target/classes/META-INF/persistence.xml

with persistence name "vtregistry" in both.

When running a JUnit test with Hibernate 5.2.4.Final, the main version is being returned which causes the tests to fail. Logs indicate that both persistence.xml files are found on the class path, with the test version first as expected when running a JUnit test.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 08:08:39.684 [main] TRACE o.h.j.b.i.PersistenceXmlParser - Attempting to parse persistence.xml file : file:/home/apps/src2/ed-mw-git/core/target/test-classes/META-INF/persistence.xml 08:08:39.748 [main] TRACE o.h.j.b.i.PersistenceXmlParser - Persistence unit name from persistence.xml : vtregistry 08:08:39.750 [main] TRACE o.h.j.b.i.PersistenceXmlParser - Attempting to parse persistence.xml file : file:/home/apps/src2/ed-mw-git/core/target/classes/META-INF/persistence.xml 08:08:39.752 [main] TRACE o.h.j.b.i.PersistenceXmlParser - Persistence unit name from persistence.xml : vtregistry 08:08:39.753 [main] DEBUG o.h.jpa.HibernatePersistenceProvider - Located and parsed 1 persistence units; checking each 08:08:39.753 [main] DEBUG o.h.jpa.HibernatePersistenceProvider - Checking persistence-unit [name=vtregistry, explicit-provider=null] against incoming persistence unit name [vtregistry] 08:08:39.754 [main] DEBUG o.h.jpa.boot.spi.ProviderChecker - No PersistenceProvider explicitly requested, assuming Hibernate 08:08:39.759 [main] DEBUG o.h.jpa.internal.util.LogHelper - PersistenceUnitInfo [ name: vtregistry persistence provider classname: null classloader: null excludeUnlistedClasses: false JTA datasource: null Non JTA datasource: null Transaction type: RESOURCE_LOCAL PU root URL: file:/home/apps/src2/ed-mw-git/core/target/classes/ Shared Cache Mode: null Validation Mode: null Jar files URLs [] Managed classes names [] Mapping files names [] Properties []

In Hibernate 5.2.2.Final the test version is correctly returned and the tests succeed. If the persistence.xml file in main is removed so that only the test version is in the class path when the tests are executed, the tests run successfully in 5.2.4.Final.

The problem seems to be related to the switch from ArrayList to ConcurrentHashMap in PersistenceXmlParser.java.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public Map<String,ParsedPersistenceXmlDescriptor> doResolve(Map integration) { final Map<String,ParsedPersistenceXmlDescriptor> persistenceUnits = new ConcurrentHashMap<>(); final List<URL> xmlUrls = classLoaderService.locateResources( "META-INF/persistence.xml" ); if ( xmlUrls.isEmpty() ) { LOG.unableToFindPersistenceXmlInClasspath(); } else { for ( URL xmlUrl : xmlUrls ) { persistenceUnits.putAll( parsePersistenceXml( xmlUrl, integration ) ); } } return persistenceUnits; } private Map<String,ParsedPersistenceXmlDescriptor> parsePersistenceXml(URL xmlUrl, Map integration) { LOG.tracef( "Attempting to parse persistence.xml file : %s", xmlUrl.toExternalForm() ); ...

parsePersistenceXml is called to process the test-classes/META-INF persistence.xml file and returns a Map entry for this test version with key vtregistry, which is added to the persistenceUnits Map in doResolve via persistenceUnits.putAll. parsePersistenceXml is then called to process the classes/META-INF persistence.xml file and returns a Map entry for this main version with the same key (vtregistry). Since the key is the same, this overwrites the test version so that only the main version is stored.

Since 5.2.2.Final used ArrayList, persistenceUnits.putAll added the test version and then the main version so that both were available for evaluation. Subsequently the test version was correctly identified and returned.

Environment

Fedora 24, Java 8, Hibernate 5.2.4.Final

Status

Assignee

Unassigned

Reporter

Catherine Winfrey

Fix versions

Labels

None

backPortable

None

Suitable for new contributors

None

Requires Release Note

None

Pull Request

None

backportDecision

None

Components

Affects versions

5.2.4

Priority

Major