HHH-11845 - Warn user when multiple persistence-units use the same name

This commit is contained in:
Andrea Boriero 2017-10-15 13:01:03 +01:00 committed by Vlad Mihalcea
parent 8e6332a964
commit 1242fd9580
3 changed files with 144 additions and 24 deletions

View File

@ -68,8 +68,8 @@ public class PersistenceXmlParser {
ClassLoaderServiceImpl.fromConfigSettings( integration ),
PersistenceUnitTransactionType.RESOURCE_LOCAL
);
return new ArrayList<>( parser.doResolve( integration ).values() );
parser.doResolve( integration );
return new ArrayList<>( parser.persistenceUnits.values() );
}
/**
@ -118,10 +118,11 @@ public class PersistenceXmlParser {
transactionType
);
final Map<String,ParsedPersistenceXmlDescriptor> persistenceUnits = parser.parsePersistenceXml( persistenceXmlUrl, integration );
assert persistenceUnits.size() == 1;
parser.parsePersistenceXml( persistenceXmlUrl, integration );
return persistenceUnits.values().iterator().next();
assert parser.persistenceUnits.size() == 1;
return parser.persistenceUnits.values().iterator().next();
}
/**
@ -173,10 +174,10 @@ public class PersistenceXmlParser {
transactionType
);
final Map<String,ParsedPersistenceXmlDescriptor> persistenceUnits = parser.parsePersistenceXml( persistenceXmlUrl, integration );
assert persistenceUnits.containsKey( name );
parser.parsePersistenceXml( persistenceXmlUrl, integration );
assert parser.persistenceUnits.containsKey( name );
return persistenceUnits.get( name );
return parser.persistenceUnits.get( name );
}
/**
@ -200,51 +201,52 @@ public class PersistenceXmlParser {
*
* @return Map of persistence-unit descriptors keyed by the PU name
*/
public static Map<String,ParsedPersistenceXmlDescriptor> parse(
public static Map<String, ParsedPersistenceXmlDescriptor> parse(
URL persistenceXmlUrl,
PersistenceUnitTransactionType transactionType,
Map integration) {
Map integration
) {
PersistenceXmlParser parser = new PersistenceXmlParser(
ClassLoaderServiceImpl.fromConfigSettings( integration ),
transactionType
);
return parser.doResolve( integration );
parser.doResolve( integration );
return parser.persistenceUnits;
}
private final ClassLoaderService classLoaderService;
private final PersistenceUnitTransactionType defaultTransactionType;
private final Map<String, ParsedPersistenceXmlDescriptor> persistenceUnits;
private PersistenceXmlParser(ClassLoaderService classLoaderService, PersistenceUnitTransactionType defaultTransactionType) {
this.classLoaderService = classLoaderService;
this.defaultTransactionType = defaultTransactionType;
this.persistenceUnits = new ConcurrentHashMap<>();
}
private Map<String,ParsedPersistenceXmlDescriptor> doResolve(Map integration) {
final Map<String,ParsedPersistenceXmlDescriptor> persistenceUnits = new ConcurrentHashMap<>();
private void doResolve(Map integration) {
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 ) );
}
parsePersistenceXml( xmlUrls, integration );
}
return persistenceUnits;
}
private Map<String,ParsedPersistenceXmlDescriptor> parsePersistenceXml(URL xmlUrl, Map integration) {
private void parsePersistenceXml(List<URL> xmlUrls, Map integration) {
for ( URL xmlUrl : xmlUrls ) {
parsePersistenceXml( xmlUrl, integration );
}
}
private void parsePersistenceXml(URL xmlUrl, Map integration) {
LOG.tracef( "Attempting to parse persistence.xml file : %s", xmlUrl.toExternalForm() );
final Document doc = loadUrl( xmlUrl );
final Element top = doc.getDocumentElement();
final Map<String,ParsedPersistenceXmlDescriptor> persistenceUnits = new ConcurrentHashMap<>();
final NodeList children = top.getChildNodes();
for ( int i = 0; i < children.getLength() ; i++ ) {
if ( children.item( i ).getNodeType() == Node.ELEMENT_NODE ) {
@ -285,7 +287,6 @@ public class PersistenceXmlParser {
}
}
}
return persistenceUnits;
}
private void decodeTransactionType(ParsedPersistenceXmlDescriptor persistenceUnit) {

View File

@ -0,0 +1,95 @@
/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.jpa.test.persistenceunit;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.jpa.boot.internal.PersistenceXmlParser;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.testing.logger.LoggerInspectionRule;
import org.hibernate.testing.logger.Triggerable;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.jboss.byteman.contrib.bmunit.BMUnitRunner;
import org.jboss.logging.Logger;
import static org.hibernate.internal.util.ConfigHelper.findAsResource;
import static org.junit.Assert.assertTrue;
/**
* @author Andrea Boriero
*/
@TestForIssue(jiraKey = "HHH-11845")
@RunWith(BMUnitRunner.class)
public class DuplicatePersistenceUnitNameTest extends BaseUnitTestCase {
private Triggerable triggerable;
@Rule
public LoggerInspectionRule logInspection = new LoggerInspectionRule(
Logger.getMessageLogger( CoreMessageLogger.class, PersistenceXmlParser.class.getName() )
);
@Before
public void setUp() {
final Set messagesPrefixes = new HashSet<>();
messagesPrefixes.add( "HHH015018" );
triggerable = logInspection.watchForLogMessages( messagesPrefixes );
}
@After
public void tearDown() {
triggerable.reset();
}
@Test
public void testDuplicatePersistenceUnitNameLogAWarnMessage() {
final Map<String, Object> properties = new HashMap<String, Object>();
properties.put( AvailableSettings.CLASSLOADERS, Arrays.asList( new TestClassLoader() ) );
PersistenceXmlParser.locatePersistenceUnits( properties );
assertTrue( "The warn HHH015018 has not been logged ", triggerable.wasTriggered() );
}
private static class TestClassLoader extends ClassLoader {
final List<URL> urls;
public TestClassLoader() {
urls = Arrays.asList(
findAsResource(
"org/hibernate/jpa/test/persistenceunit/META-INF/persistence.xml"
)
,
findAsResource(
"org/hibernate/jpa/test/persistenceunit/META-INF/persistenceUnitForNameDuplicationTest.xml"
)
);
}
@Override
protected Enumeration<URL> findResources(String name) throws IOException {
return name.equals( "META-INF/persistence.xml" ) ?
Collections.enumeration( urls ) :
Collections.emptyEnumeration();
}
}
}

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Hibernate, Relational Persistence for Idiomatic Java
~
~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
-->
<persistence 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"
version="2.1">
<!--
The PU name is also present in the persistence.xml located in the same folder,
this should cause a warn message to be logged.
See org.hibernate.jpa.test.persistenceunit.DuplicatePersistenceUnitNameTest
-->
<persistence-unit name="ExcludeUnlistedClassesTest1" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>org.hibernate.jpa.test.persistenceunit.DataPoint</class>
</persistence-unit>
</persistence>