/** * Initialize all persistence units found on initializationClassLoader. Initialization is a two * phase process. First the predeploy process builds the metadata and creates any required * transformers. Second the deploy process creates an EclipseLink session based on that metadata. */ protected void initPersistenceUnits(Archive archive, Map m) { Iterator<SEPersistenceUnitInfo> persistenceUnits = PersistenceUnitProcessor.getPersistenceUnits(archive, initializationClassloader).iterator(); while (persistenceUnits.hasNext()) { SEPersistenceUnitInfo persistenceUnitInfo = persistenceUnits.next(); if (isPersistenceProviderSupported(persistenceUnitInfo.getPersistenceProviderClassName())) { // puName uniquely defines the pu on a class loader String puName = persistenceUnitInfo.getPersistenceUnitName(); // don't add puInfo that could not be used standalone (only as composite member). if (EntityManagerSetupImpl.mustBeCompositeMember(persistenceUnitInfo)) { continue; } // If puName is already in the map then there are two jars containing persistence units with // the same name. // Because both are loaded from the same classloader there is no way to distinguish between // them - throw exception. EntityManagerSetupImpl anotherEmSetupImpl = null; if (initialEmSetupImpls != null) { anotherEmSetupImpl = this.initialEmSetupImpls.get(puName); } if (anotherEmSetupImpl != null) { EntityManagerSetupImpl.throwPersistenceUnitNameAlreadyInUseException( puName, persistenceUnitInfo, anotherEmSetupImpl.getPersistenceUnitInfo()); } // Note that session name is extracted only from puInfo, the passed properties ignored. String sessionName = EntityManagerSetupImpl.getOrBuildSessionName( Collections.emptyMap(), persistenceUnitInfo, puName); EntityManagerSetupImpl emSetupImpl = callPredeploy(persistenceUnitInfo, m, puName, sessionName); if (initialEmSetupImpls != null) { this.initialEmSetupImpls.put(puName, emSetupImpl); } if (initialPuInfos != null) { this.initialPuInfos.put(puName, persistenceUnitInfo); } } } }
/** * predeploy (with deploy) is one of the two steps required in deployment of entities This method * will prepare to call predeploy, call it and finally register the transformer returned to be * used for weaving. */ public EntityManagerSetupImpl callPredeploy( SEPersistenceUnitInfo persistenceUnitInfo, Map m, String persistenceUnitUniqueName, String sessionName) { AbstractSessionLog.getLog() .log( SessionLog.FINER, "cmp_init_invoke_predeploy", persistenceUnitInfo.getPersistenceUnitName()); Map mergedProperties = EntityManagerFactoryProvider.mergeMaps(m, persistenceUnitInfo.getProperties()); // Bug#4452468 When globalInstrumentation is null, there is no weaving checkWeaving(mergedProperties); Set tempLoaderSet = PersistenceUnitProcessor.buildClassSet(persistenceUnitInfo, m); // Create the temp loader that will not cache classes for entities in our persistence unit ClassLoader tempLoader = createTempLoader(tempLoaderSet); persistenceUnitInfo.setNewTempClassLoader(tempLoader); EntityManagerSetupImpl emSetupImpl = new EntityManagerSetupImpl(persistenceUnitUniqueName, sessionName); // A call to predeploy will partially build the session we will use final ClassTransformer transformer = emSetupImpl.predeploy(persistenceUnitInfo, mergedProperties); // After preDeploy it's impossible to weave again - so may substitute the temporary classloader // with the real one. // The temporary classloader could be garbage collected even if the puInfo is cached for the // future use by other emSetupImpls. persistenceUnitInfo.setNewTempClassLoader(persistenceUnitInfo.getClassLoader()); registerTransformer(transformer, persistenceUnitInfo, m); return emSetupImpl; }