From c11a29742027c1475b4afc7f24f4c9e317928e3b Mon Sep 17 00:00:00 2001 From: Steve Ebersole Date: Thu, 9 Sep 2010 03:35:35 +0000 Subject: [PATCH] HHH-5543 - JEE bootstrapping should only parse and validate mapping files once git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@20325 1b8cb986-b30d-0410-93ca-fae66ebed9b2 --- .../java/org/hibernate/cfg/Configuration.java | 2 +- .../org/hibernate/ejb/Ejb3Configuration.java | 49 ++++++++++++++++--- 2 files changed, 42 insertions(+), 9 deletions(-) diff --git a/core/src/main/java/org/hibernate/cfg/Configuration.java b/core/src/main/java/org/hibernate/cfg/Configuration.java index 4775223c25..a5d378e1bf 100644 --- a/core/src/main/java/org/hibernate/cfg/Configuration.java +++ b/core/src/main/java/org/hibernate/cfg/Configuration.java @@ -510,7 +510,7 @@ private XmlDocument add(InputSource inputSource, Origin origin) { return metadataXml; } - private void add(XmlDocument metadataXml) { + public void add(XmlDocument metadataXml) { if ( inSecondPass || !isOrmXml( metadataXml ) ) { metadataSourceQueue.add( metadataXml ); } diff --git a/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java b/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java index 27747cd720..95dd417454 100644 --- a/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java +++ b/entitymanager/src/main/java/org/hibernate/ejb/Ejb3Configuration.java @@ -98,9 +98,7 @@ import org.hibernate.util.CollectionHelper; import org.hibernate.util.ReflectHelper; import org.hibernate.util.StringHelper; -import org.hibernate.util.XMLHelper; import org.hibernate.util.xml.MappingReader; -import org.hibernate.util.xml.Origin; import org.hibernate.util.xml.OriginImpl; import org.hibernate.util.xml.XmlDocument; @@ -122,13 +120,13 @@ * @author Emmanuel Bernard */ public class Ejb3Configuration implements Serializable, Referenceable { + private final Logger log = LoggerFactory.getLogger( Ejb3Configuration.class ); private static final String IMPLEMENTATION_NAME = HibernatePersistence.class.getName(); private static final String META_INF_ORM_XML = "META-INF/orm.xml"; - private final Logger log = LoggerFactory.getLogger( Ejb3Configuration.class ); + private static final String PARSED_MAPPING_DOMS = "hibernate.internal.mapping_doms"; + private static EntityNotFoundDelegate ejb3EntityNotFoundDelegate = new Ejb3EntityNotFoundDelegate(); private static Configuration DEFAULT_CONFIGURATION = new AnnotationConfiguration(); - private String persistenceUnitName; - private String cfgXmlResource; private static class Ejb3EntityNotFoundDelegate implements EntityNotFoundDelegate, Serializable { public void handleEntityNotFound(String entityName, Serializable id) { @@ -140,6 +138,9 @@ public void handleEntityNotFound(String entityName, Serializable id) { Version.touch(); } + private String persistenceUnitName; + private String cfgXmlResource; + private AnnotationConfiguration cfg; private SettingsFactory settingsFactory; //made transient and not restored in deserialization on purpose, should no longer be called after restoration @@ -562,6 +563,7 @@ public Ejb3Configuration configure(PersistenceUnitInfo info, Map integration) { List hbmFiles = new ArrayList(); List packages = new ArrayList(); List xmlFiles = new ArrayList( 50 ); + List xmlDocuments = new ArrayList( 50 ); if ( info.getMappingFileNames() != null ) { xmlFiles.addAll( info.getMappingFileNames() ); } @@ -592,7 +594,7 @@ public Ejb3Configuration configure(PersistenceUnitInfo info, Map integration) { //FIXME entities is used to enhance classes and to collect annotated entities this should not be mixed //fill up entities with the on found in xml files - addXMLEntities( xmlFiles, info, entities ); + addXMLEntities( xmlFiles, info, entities, xmlDocuments ); //FIXME send the appropriate entites. if ( "true".equalsIgnoreCase( properties.getProperty( AvailableSettings.USE_CLASS_ENHANCER ) ) ) { @@ -602,7 +604,11 @@ public Ejb3Configuration configure(PersistenceUnitInfo info, Map integration) { workingVars.put( AvailableSettings.CLASS_NAMES, entities ); workingVars.put( AvailableSettings.PACKAGE_NAMES, packages ); workingVars.put( AvailableSettings.XML_FILE_NAMES, xmlFiles ); - if ( hbmFiles.size() > 0 ) workingVars.put( AvailableSettings.HBXML_FILES, hbmFiles ); + workingVars.put( PARSED_MAPPING_DOMS, xmlDocuments ); + + if ( hbmFiles.size() > 0 ) { + workingVars.put( AvailableSettings.HBXML_FILES, hbmFiles ); + } // validation factory final Object validationFactory = integration.get( AvailableSettings.VALIDATION_FACTORY ); @@ -687,7 +693,23 @@ else if ( isJTA == Boolean.FALSE ) { return this; } - private void addXMLEntities(List xmlFiles, PersistenceUnitInfo info, List entities) { + /** + * Processes {@code xmlFiles} argument and populates:
    + *
  • the {@code entities} list with encountered classnames
  • + *
  • the {@code xmlDocuments} list with parsed/validated {@link XmlDocument} corrolary to each xml file
  • + *
+ * + * @param xmlFiles The XML resource names; these will be resolved by classpath lookup and parsed/validated. + * @param info The PUI + * @param entities (output) The names of all encountered "mapped" classes + * @param xmlDocuments (output) The list of {@link XmlDocument} instances of each entry in {@code xmlFiles} + */ + @SuppressWarnings({ "unchecked" }) + private void addXMLEntities( + List xmlFiles, + PersistenceUnitInfo info, + List entities, + List xmlDocuments) { //TODO handle inputstream related hbm files ClassLoader classLoaderToUse = info.getNewTempClassLoader(); if ( classLoaderToUse == null ) { @@ -710,6 +732,7 @@ private void addXMLEntities(List xmlFiles, PersistenceUnitInfo info, Lis inputSource, new OriginImpl( "persistence-unit-info", xmlFile ) ); + xmlDocuments.add( metadataXml ); try { final Element rootElement = metadataXml.getDocumentTree().getRootElement(); if ( rootElement != null && "entity-mappings".equals( rootElement.getName() ) ) { @@ -750,6 +773,7 @@ else if ( rootElement != null && "hibernate-mappings".equals( rootElement.getNam } } } + xmlFiles.clear(); } private void defineTransactionType(Object overridenTxType, Map workingVars) { @@ -1081,6 +1105,7 @@ else if ( propertyKey.startsWith( AvailableSettings.JACC_PREFIX ) return this; } + @SuppressWarnings({ "unchecked" }) private void addClassesToSessionFactory(Map workingVars) { if ( workingVars.containsKey( AvailableSettings.CLASS_NAMES ) ) { Collection classNames = (Collection) workingVars.get( @@ -1088,6 +1113,14 @@ private void addClassesToSessionFactory(Map workingVars) { ); addNamedAnnotatedClasses( this, classNames, workingVars ); } + + if ( workingVars.containsKey( PARSED_MAPPING_DOMS ) ) { + Collection xmlDocuments = (Collection) workingVars.get( PARSED_MAPPING_DOMS ); + for ( XmlDocument xmlDocument : xmlDocuments ) { + cfg.add( xmlDocument ); + } + } + //TODO apparently only used for Tests, get rid of it? if ( workingVars.containsKey( AvailableSettings.LOADED_CLASSES ) ) { Collection classes = (Collection) workingVars.get( AvailableSettings.LOADED_CLASSES );