================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tltest/source/entity-persistence-tests/src/java/oracle/toplink/essentials/testing/tests/cmp3/advanced/EntityManagerJUnitTestSuite.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000001/AB0952363AC40CBFE034080020E8C54E.62 Report generated at Fri Dec 15 17:18:58 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000001/AB0952363AC40CBFE034080020E8C54E.62 Fri Dec 15 16:48:40 2006 --- /ade/ailitche_toplink_main/tltest/source/entity-persistence-tests/src/java/oracle/toplink/essentials/testing/tests/cmp3/advanced/EntityManagerJUnitTestSuite.java Fri Dec 15 17:18:57 2006 *************** *** 3690,3695 **** --- 3690,3718 ---- } } + // gf1732 + public void testMultipleEntityManagerFactories() { + // close the original factory + closeEntityManagerFactory(); + // create the new one - not yet deployed + EntityManagerFactory factory1 = getEntityManagerFactory(); + // create the second one + EntityManagerFactory factory2 = Persistence.createEntityManagerFactory("default", getDatabaseProperties()); + // deploy + factory2.createEntityManager(); + // close + factory2.close(); + + try { + // now try to getEM from the first one - this used to throw exception + factory1.createEntityManager(); + // don't close factory1 if all is well + } catch (PersistenceException ex) { + fail("factory1.createEM threw exception: " + ex.getMessage()); + factory1.close(); + } + } + public static void main(String[] args) { // Now run JUnit. junit.swingui.TestRunner.main(args); ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/ejb/cmp3/EntityManagerFactoryProvider.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000002/AB0952363AC40CBFE034080020E8C54E.53 Report generated at Fri Dec 15 17:18:58 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000002/AB0952363AC40CBFE034080020E8C54E.53 Fri Dec 15 16:53:31 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/ejb/cmp3/EntityManagerFactoryProvider.java Fri Dec 15 17:18:57 2006 *************** *** 122,141 **** if (emSetupImpl == null) { throw new PersistenceException(EntityManagerSetupException.puNotExist(name)); } ! if(emSetupImpl.isUndeployed()) { ! ((SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo()).setClassLoader(JavaSECMPInitializer.getMainLoader()); ! ((SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo()).setNewTempClassLoader(JavaSECMPInitializer.getMainLoader()); ! // the first parameter is ignored if predeploy called after undeploy emSetupImpl.predeploy(null, nonNullProperties); } ! EntityManagerFactoryImpl factory = new EntityManagerFactoryImpl(emSetupImpl, nonNullProperties); ! ! // This code has been added to allow validation to occur without actually calling createEntityManager ! if (emSetupImpl.shouldGetSessionOnCreateFactory(nonNullProperties)) { ! factory.getServerSession(); } - return factory; } /** --- 122,162 ---- if (emSetupImpl == null) { throw new PersistenceException(EntityManagerSetupException.puNotExist(name)); } ! ! // synchronized to prevent overriding of the class loader ! // and also calls to predeploy and undeploy by other threads - ! // the latter may alter result of shouldRedeploy method. ! synchronized(emSetupImpl) { ! if(emSetupImpl.shouldRedeploy()) { ! SEPersistenceUnitInfo persistenceInfo = (SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo(); ! persistenceInfo.setClassLoader(JavaSECMPInitializer.getMainLoader()); ! persistenceInfo.setNewTempClassLoader(JavaSECMPInitializer.getMainLoader()); ! } ! // the first parameter is ignored - persistenceInfo has been already passed ! // when predeploy first called by JavaSECMPInitializer. ! // If shouldRedeploy is true, then predeploy creates a new session, ! // otherwise it only increments factoryCount. ! // emSetupImpl.predeploy(null, nonNullProperties); } ! EntityManagerFactoryImpl factory = null; ! try { ! factory = new EntityManagerFactoryImpl(emSetupImpl, nonNullProperties); ! ! // This code has been added to allow validation to occur without actually calling createEntityManager ! if (emSetupImpl.shouldGetSessionOnCreateFactory(nonNullProperties)) { ! factory.getServerSession(); ! } ! return factory; ! } catch (RuntimeException ex) { ! if(factory != null) { ! factory.close(); ! } else { ! emSetupImpl.undeploy(); ! } ! throw ex; } } /** ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/exceptions/EntityManagerSetupException.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.11 Report generated at Fri Dec 15 17:18:58 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.11 Fri Dec 15 16:54:50 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/exceptions/EntityManagerSetupException.java Fri Dec 15 17:18:57 2006 *************** *** 40,45 **** --- 40,48 ---- public static final int FAILED_WHILE_PROCESSING_PROPERTY = 28014; public static final int FAILED_TO_INSTANTIATE_LOGGER = 28015; public static final int PU_NOT_EXIST = 28016; + public static final int CANNOT_PREDEPLOY = 28017; + public static final int PREDEPLOY_FAILED = 28018; + public static final int DEPLOY_FAILED = 28019; /** *************** *** 163,170 **** return setupException; } ! public static EntityManagerSetupException cannotDeployWithoutPredeploy(String persistenceUnitName) { ! Object[] args = { persistenceUnitName }; EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, CANNOT_DEPLOY_WITHOUT_PREDEPLOY, args)); setupException.setErrorCode(CANNOT_DEPLOY_WITHOUT_PREDEPLOY); --- 166,173 ---- return setupException; } ! public static EntityManagerSetupException cannotDeployWithoutPredeploy(String persistenceUnitName, String state) { ! Object[] args = { persistenceUnitName, state }; EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, CANNOT_DEPLOY_WITHOUT_PREDEPLOY, args)); setupException.setErrorCode(CANNOT_DEPLOY_WITHOUT_PREDEPLOY); *************** *** 194,197 **** --- 197,224 ---- setupException.setErrorCode(PU_NOT_EXIST); return setupException; } + + public static EntityManagerSetupException cannotPredeploy(String persistenceUnitName, String state) { + Object[] args = { persistenceUnitName, state }; + + EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, CANNOT_PREDEPLOY, args)); + setupException.setErrorCode(CANNOT_PREDEPLOY); + return setupException; + } + + public static EntityManagerSetupException predeployFailed(String persistenceUnitName, RuntimeException exception) { + Object[] args = { persistenceUnitName }; + + EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, PREDEPLOY_FAILED, args), exception); + setupException.setErrorCode(PREDEPLOY_FAILED); + return setupException; + } + + public static EntityManagerSetupException deployFailed(String persistenceUnitName, RuntimeException exception) { + Object[] args = { persistenceUnitName }; + + EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, DEPLOY_FAILED, args), exception); + setupException.setErrorCode(DEPLOY_FAILED); + return setupException; + } } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/EntityManagerSetupExceptionResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000004/AB0952363AC40CBFE034080020E8C54E.15 Report generated at Fri Dec 15 17:18:58 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000004/AB0952363AC40CBFE034080020E8C54E.15 Fri Dec 15 16:55:12 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/EntityManagerSetupExceptionResource.java Fri Dec 15 17:18:57 2006 *************** *** 43,52 **** { "28010", "PersistenceUnitInfo {0} has transactionType JTA, but doesn't have jtaDataSource." }, { "28011", "The session, [{0}], built for a persistence unit was not available at the time it was deployed. This means that somehow the session was removed from the container in the middle of the deployment process." }, { "28012", "Value [{0}] is of incorrect type for property [{2}], value type should be [{1}]." }, ! { "28013", "Attempted to deploy PersistenceUnit [{0}] for which predeploy method either had not called or had failed" }, { "28014", "Exception was thrown while processing property [{0}] with value {[1}]." }, { "28015", "Failed to instantiate SessionLog of type [{0}] specified in [{1}] property." }, ! { "28016", "The persistence unit with name [{0}] does not exist." } }; /** --- 43,55 ---- { "28010", "PersistenceUnitInfo {0} has transactionType JTA, but doesn't have jtaDataSource." }, { "28011", "The session, [{0}], built for a persistence unit was not available at the time it was deployed. This means that somehow the session was removed from the container in the middle of the deployment process." }, { "28012", "Value [{0}] is of incorrect type for property [{2}], value type should be [{1}]." }, ! { "28013", "Attempted to deploy PersistenceUnit [{0}] while being in the wrong state [{1}]. Close all factories for this PersistenceUnit." }, { "28014", "Exception was thrown while processing property [{0}] with value {[1}]." }, { "28015", "Failed to instantiate SessionLog of type [{0}] specified in [{1}] property." }, ! { "28016", "The persistence unit with name [{0}] does not exist." }, ! {"28017", "Attempted to predeploy PersistenceUnit [{0}] while being in the wrong state [{1}]." }, ! {"28018", "predeploy for PersistenceUnit [{0}] failed." }, ! {"28019", "deploy for PersistenceUnit [{0}] failed. Close all factories for this PersistenceUnit." } }; /** ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/base/EntityManagerFactoryImpl.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000005/AB0952363AC40CBFE034080020E8C54E.15 Report generated at Fri Dec 15 17:18:58 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000005/AB0952363AC40CBFE034080020E8C54E.15 Fri Dec 15 16:56:33 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/base/EntityManagerFactoryImpl.java Fri Dec 15 17:18:57 2006 *************** *** 89,97 **** public synchronized void close(){ verifyOpen(); isOpen = false; ! if(serverSession != null) { ! setupImpl.undeploy(); ! } } --- 89,95 ---- public synchronized void close(){ verifyOpen(); isOpen = false; ! setupImpl.undeploy(); } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/EntityManagerSetupImpl.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000006/AB0952363AC40CBFE034080020E8C54E.82 Report generated at Fri Dec 15 17:18:58 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000006/AB0952363AC40CBFE034080020E8C54E.82 Fri Dec 15 16:57:04 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/EntityManagerSetupImpl.java Fri Dec 15 17:18:57 2006 *************** *** 37,43 **** import oracle.toplink.essentials.internal.weaving.TransformerFactory; import oracle.toplink.essentials.jndi.JNDIConnector; import oracle.toplink.essentials.logging.AbstractSessionLog; - import oracle.toplink.essentials.logging.DefaultSessionLog; import oracle.toplink.essentials.logging.SessionLog; import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper; import oracle.toplink.essentials.internal.security.PrivilegedClassForName; --- 37,42 ---- *************** *** 52,58 **** import oracle.toplink.essentials.internal.ejb.cmp3.base.CMP3Policy; import oracle.toplink.essentials.platform.server.CustomServerPlatform; import oracle.toplink.essentials.platform.server.ServerPlatform; - import oracle.toplink.essentials.platform.server.NoServerPlatform; import oracle.toplink.essentials.exceptions.*; import oracle.toplink.essentials.internal.helper.EJB30ConversionManager; import javax.persistence.spi.PersistenceUnitTransactionType; --- 51,56 ---- *************** *** 80,101 **** protected MetadataProcessor processor = null; protected PersistenceUnitInfo persistenceUnitInfo = null; protected Map predeployProperties = null; ! // may be positive only in STATE_DEPLOYED ! protected int deploymentCount = 0; protected ServerSession session = null; protected boolean isInContainerMode = false; // indicates whether weaving was used on the first run through predeploy (in STATE_INITIAL) protected boolean enableLazyForOneToOne = false; protected SecurableObjectHolder securableObjectHolder = new SecurableObjectHolder(); ! public static final String STATE_INITIAL = "Initial"; ! public static final String STATE_PREDEPLOYED = "Predeployed"; ! public static final String STATE_DEPLOYED = "Deployed"; ! public static final String STATE_UNDEPLOYED = "Undeployed"; protected String state = STATE_INITIAL; ! public static final String ERROR_LOADING_XML_FILE = "error_loading_xml_file"; public static final String EXCEPTION_LOADING_ENTITY_CLASS = "exception_loading_entity_class"; /** --- 78,126 ---- protected MetadataProcessor processor = null; protected PersistenceUnitInfo persistenceUnitInfo = null; protected Map predeployProperties = null; ! // count a number of open factories that use this object. ! protected int factoryCount = 0; protected ServerSession session = null; + // true if predeploy called by createContainerEntityManagerFactory; false - createEntityManagerFactory protected boolean isInContainerMode = false; // indicates whether weaving was used on the first run through predeploy (in STATE_INITIAL) protected boolean enableLazyForOneToOne = false; protected SecurableObjectHolder securableObjectHolder = new SecurableObjectHolder(); ! // factoryCount==0; session==null ! public static final String STATE_INITIAL = "Initial"; ! ! // session != null ! public static final String STATE_PREDEPLOYED = "Predeployed"; ! ! // factoryCount>0; session != null; session stored in SessionManager ! public static final String STATE_DEPLOYED = "Deployed"; ! ! // factoryCount==0; session==null ! public static final String STATE_PREDEPLOY_FAILED="PredeployFailed"; ! ! // factoryCount>0; session != null ! public static final String STATE_DEPLOY_FAILED = "DeployFailed"; ! ! // factoryCount==0; session==null ! public static final String STATE_UNDEPLOYED = "Undeployed"; protected String state = STATE_INITIAL; ! /** ! * Initial -----> PredeployFailed ! * | | ! * V V ! * |-> Predeployed --> DeployFailed ! * | | | | ! * | V V V ! * | Deployed -> Undeployed-->| ! * | | ! * |<-------------------------V ! */ ! ! ! public static final String ERROR_LOADING_XML_FILE = "error_loading_xml_file"; public static final String EXCEPTION_LOADING_ENTITY_CLASS = "exception_loading_entity_class"; /** *************** *** 121,188 **** * the predeploy phase we were in a stage where we were not let allowed to load the real classes. * * Deploy could be called several times - but only the first call does the actual deploying - ! * additional calls allow to update session properties (provided the session is not connected) and ! * encrease deploymentCount (which decreased by calls to undeploy method). ! * * @param realClassLoader The class loader that was used to load the entity classes. This loader * will be maintained for the lifespan of the loaded classes. * @param additionalProperties added to predeployProperties for updateServerSession overriding existing properties. * In JSE case it allows to alter properties in main (as opposed to preMain where preDeploy is called). * @return An EntityManagerFactory to be used by the Container to obtain EntityManagers */ ! public synchronized ServerSession deploy(ClassLoader realClassLoader, Map additionalProperties) { if(state != STATE_PREDEPLOYED && state != STATE_DEPLOYED) { ! throw new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(persistenceUnitInfo.getPersistenceUnitName())); } ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount}); try { Map deployProperties = mergeMaps(additionalProperties, predeployProperties); translateOldProperties(deployProperties, session); if(state == STATE_PREDEPLOYED) { ! // The project is initially created using class names rather than classes. This call will make the conversion ! session.getProject().convertClassNamesToClasses(realClassLoader); ! ! // listeners and queries require the real classes and are therefore built during deploy using the realClassLoader ! processor.setClassLoader(realClassLoader); ! processor.addEntityListeners(); ! processor.addNamedQueries(); ! // free the resouces that we don't need any more. ! processor.cleanup(); ! processor = null; ! ! initServerSession(deployProperties); ! ! if (session.getIntegrityChecker().hasErrors()){ ! session.handleException(new IntegrityException(session.getIntegrityChecker())); } - - session.getDatasourcePlatform().getConversionManager().setLoader(realClassLoader); } ! deploymentCount++; ! state = STATE_DEPLOYED; ! try{ ! updateServerSession(deployProperties); ! if(!session.isConnected()) { ! if(isValidationOnly(deployProperties, false)) { ! session.initializeDescriptors(); ! } else { ! login(session, deployProperties); ! generateDDLFiles(session, deployProperties, !isInContainerMode); } } - } catch (RuntimeException exception) { - cleanUpSessionManager(); - throw exception; } return session; } catch (oracle.toplink.essentials.exceptions.ValidationException exception) { throw new javax.persistence.PersistenceException(exception); } finally { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount}); ! if(state == STATE_UNDEPLOYED) { ! session = null; ! } } } --- 146,225 ---- * the predeploy phase we were in a stage where we were not let allowed to load the real classes. * * Deploy could be called several times - but only the first call does the actual deploying - ! * additional calls allow to update session properties (in case the session is not connected). ! * ! * Note that there is no need to synchronize deploy method - it doesn't alter factoryCount ! * and while deploy is executed no other method can alter the current state ! * (predeploy call would just increment factoryCount; undeploy call would not drop factoryCount to 0). ! * However precautions should be taken to handle concurrent calls to deploy, because those may ! * alter the current state or connect the session. ! * * @param realClassLoader The class loader that was used to load the entity classes. This loader * will be maintained for the lifespan of the loaded classes. * @param additionalProperties added to predeployProperties for updateServerSession overriding existing properties. * In JSE case it allows to alter properties in main (as opposed to preMain where preDeploy is called). * @return An EntityManagerFactory to be used by the Container to obtain EntityManagers */ ! public ServerSession deploy(ClassLoader realClassLoader, Map additionalProperties) { if(state != STATE_PREDEPLOYED && state != STATE_DEPLOYED) { ! throw new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(persistenceUnitInfo.getPersistenceUnitName(), state)); } ! // state is PREDEPLOYED or DEPLOYED ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); try { Map deployProperties = mergeMaps(additionalProperties, predeployProperties); translateOldProperties(deployProperties, session); if(state == STATE_PREDEPLOYED) { ! synchronized(session) { ! if(state == STATE_PREDEPLOYED) { ! try { ! // The project is initially created using class names rather than classes. This call will make the conversion ! session.getProject().convertClassNamesToClasses(realClassLoader); ! ! // listeners and queries require the real classes and are therefore built during deploy using the realClassLoader ! processor.setClassLoader(realClassLoader); ! processor.addEntityListeners(); ! processor.addNamedQueries(); ! // free the resouces that we don't need any more. ! processor.cleanup(); ! processor = null; ! ! initServerSession(deployProperties); ! ! if (session.getIntegrityChecker().hasErrors()){ ! session.handleException(new IntegrityException(session.getIntegrityChecker())); ! } ! ! session.getDatasourcePlatform().getConversionManager().setLoader(realClassLoader); ! state = STATE_DEPLOYED; ! } catch (RuntimeException ex) { ! state = STATE_DEPLOY_FAILED; ! // session not discarded here only because it will be used in undeploy method for debug logging. ! throw new PersistenceException(EntityManagerSetupException.deployFailed(persistenceUnitInfo.getPersistenceUnitName(), ex)); ! } ! } } } ! // state is DEPLOYED ! if(!session.isConnected()) { ! synchronized(session) { ! if(!session.isConnected()) { ! updateServerSession(deployProperties); ! if(isValidationOnly(deployProperties, false)) { ! session.initializeDescriptors(); ! } else { ! login(session, deployProperties); ! generateDDLFiles(session, deployProperties, !isInContainerMode); ! } } } } return session; } catch (oracle.toplink.essentials.exceptions.ValidationException exception) { throw new javax.persistence.PersistenceException(exception); } finally { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); } } *************** *** 459,537 **** /** * Perform any steps necessary prior to actual deployment. This includes any steps in the session * creation that do not require the real loaded domain classes. * * @return A transformer (which may be null) that should be plugged into the proper * classloader to allow classes to be transformed as they get loaded. * @see #predeploy(javax.persistence.spi.PersistenceUnitInfo, java.util.Map) */ ! public ClassTransformer predeploy(PersistenceUnitInfo info, Map extendedProperties) { ! if(state == STATE_INITIAL) { persistenceUnitInfo = info; } ! ClassLoader privateClassLoader = persistenceUnitInfo.getNewTempClassLoader(); ! predeployProperties = mergeMaps(extendedProperties, persistenceUnitInfo.getProperties()); ! ! // translate old properties ! // this should be done before using properties (i.e. ServerPlatform) ! translateOldProperties(predeployProperties, null); ! ! // create server session (it should be done before initializing ServerPlatform) ! session = new ServerSession(new Project(new DatabaseLogin())); ! ! // ServerSession name and ServerPlatform must be set prior to setting the loggers. ! setServerSessionName(predeployProperties); ! updateServerPlatform(predeployProperties); ! // Update loggers and settings for the singleton logger and the session logger. ! updateLoggers(predeployProperties, true, false); ! warnOldProperties(predeployProperties, session); ! ! session.getPlatform().setConversionManager(new EJB30ConversionManager()); ! if(!isValidationOnly(predeployProperties, false) && persistenceUnitInfo != null && persistenceUnitInfo.getTransactionType() == PersistenceUnitTransactionType.JTA) { ! if(persistenceUnitInfo.getJtaDataSource() == null) { ! throw new PersistenceException(EntityManagerSetupException.jtaPersistenceUnitInfoMissingJtaDataSource(persistenceUnitInfo.getPersistenceUnitName())); } ! } ! ! // this flag is used to disable work done as a result of the LAZY hint on OneToOne mappings ! if(state == STATE_INITIAL ) { ! enableLazyForOneToOne = true; ! String weaving = getConfigPropertyAsString(TopLinkProperties.WEAVING); ! if (weaving != null && weaving.equalsIgnoreCase("false")) { ! enableLazyForOneToOne = false; } } - - boolean throwExceptionOnFail = "true".equalsIgnoreCase( - EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(EntityManagerFactoryProvider.TOPLINK_ORM_THROW_EXCEPTIONS, predeployProperties, "true", session)); - - // Create an instance of MetadataProcessor for specified persistence unit info - processor = new MetadataProcessor(persistenceUnitInfo, session, privateClassLoader, enableLazyForOneToOne); - - // Process the Object/relational metadata from XML and annotations. - PersistenceUnitProcessor.processORMetadata(processor,privateClassLoader, session,throwExceptionOnFail); - - - // The connector will be reconstructed when the session is actually deployed - session.getProject().getLogin().setConnector(new DefaultConnector()); - - if (session.getIntegrityChecker().hasErrors()){ - session.handleException(new IntegrityException(session.getIntegrityChecker())); - } - - // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings. It will only - // be returned if we we are mean to process these mappings - ClassTransformer transformer = null; - if (enableLazyForOneToOne){ - // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use - Collection entities = PersistenceUnitProcessor.buildEntityList(processor,privateClassLoader); - transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); - } - - state = STATE_PREDEPLOYED; - return transformer; } --- 496,611 ---- /** * Perform any steps necessary prior to actual deployment. This includes any steps in the session * creation that do not require the real loaded domain classes. + * + * The first call to this method caches persistenceUnitInfo which is reused in the following calls. + * + * Note that in JSE case factoryCount is NOT incremented on the very first call + * (by JavaSECMPInitializer.callPredeploy, typically in preMain). + * That provides 1 to 1 correspondence between factoryCount and the number of open factories. + * + * In case factoryCount > 0 the method just increments factoryCount. + * factory == 0 triggers creation of a new session. + * + * This method and undeploy - the only methods altering factoryCount - should be synchronized. * * @return A transformer (which may be null) that should be plugged into the proper * classloader to allow classes to be transformed as they get loaded. * @see #predeploy(javax.persistence.spi.PersistenceUnitInfo, java.util.Map) */ ! public synchronized ClassTransformer predeploy(PersistenceUnitInfo info, Map extendedProperties) { ! if(state == STATE_DEPLOY_FAILED) { ! throw new PersistenceException(EntityManagerSetupException.cannotPredeploy(persistenceUnitInfo.getPersistenceUnitName(), state)); ! } ! if(state == STATE_PREDEPLOYED || state == STATE_DEPLOYED) { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "predeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); ! factoryCount++; ! if(session != null) { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); ! } ! return null; ! } else if(state == STATE_INITIAL) { persistenceUnitInfo = info; } ! // state is INITIAL, PREDEPLOY_FAILED or UNDEPLOYED ! try { ! ClassLoader privateClassLoader = persistenceUnitInfo.getNewTempClassLoader(); ! // create server session (it should be done before initializing ServerPlatform) ! // (also before translateOldProperties - it requires session to log warnings) ! session = new ServerSession(new Project(new DatabaseLogin())); ! ! predeployProperties = mergeMaps(extendedProperties, persistenceUnitInfo.getProperties()); ! ! // translate old properties ! // this should be done before using properties (i.e. ServerPlatform) ! translateOldProperties(predeployProperties, null); ! ! // ServerSession name and ServerPlatform must be set prior to setting the loggers. ! setServerSessionName(predeployProperties); ! updateServerPlatform(predeployProperties); ! ! // Update loggers and settings for the singleton logger and the session logger. ! updateLoggers(predeployProperties, true, false); ! ! warnOldProperties(predeployProperties, session); ! ! session.getPlatform().setConversionManager(new EJB30ConversionManager()); ! if(!isValidationOnly(predeployProperties, false) && persistenceUnitInfo != null && persistenceUnitInfo.getTransactionType() == PersistenceUnitTransactionType.JTA) { ! if(persistenceUnitInfo.getJtaDataSource() == null) { ! throw new PersistenceException(EntityManagerSetupException.jtaPersistenceUnitInfoMissingJtaDataSource(persistenceUnitInfo.getPersistenceUnitName())); ! } ! } ! ! // this flag is used to disable work done as a result of the LAZY hint on OneToOne mappings ! if(state == STATE_INITIAL ) { ! enableLazyForOneToOne = true; ! String weaving = getConfigPropertyAsString(TopLinkProperties.WEAVING); ! if (weaving != null && weaving.equalsIgnoreCase("false")) { ! enableLazyForOneToOne = false; ! } ! } ! ! boolean throwExceptionOnFail = "true".equalsIgnoreCase( ! EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(EntityManagerFactoryProvider.TOPLINK_ORM_THROW_EXCEPTIONS, predeployProperties, "true", session)); ! ! // Create an instance of MetadataProcessor for specified persistence unit info ! processor = new MetadataProcessor(persistenceUnitInfo, session, privateClassLoader, enableLazyForOneToOne); ! ! // Process the Object/relational metadata from XML and annotations. ! PersistenceUnitProcessor.processORMetadata(processor,privateClassLoader, session,throwExceptionOnFail); ! ! ! // The connector will be reconstructed when the session is actually deployed ! session.getProject().getLogin().setConnector(new DefaultConnector()); ! if (session.getIntegrityChecker().hasErrors()){ ! session.handleException(new IntegrityException(session.getIntegrityChecker())); } ! ! // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings. It will only ! // be returned if we we are mean to process these mappings ! ClassTransformer transformer = null; ! if (enableLazyForOneToOne){ ! // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use ! Collection entities = PersistenceUnitProcessor.buildEntityList(processor,privateClassLoader); ! transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); } + + // factoryCount is not incremented only in case of a first call to preDeploy + // in non-container mode: this call is not associated with a factory + // but rather done by JavaSECMPInitializer.callPredeploy (typically in preMain). + if(state != STATE_INITIAL || this.isInContainerMode()) { + factoryCount++; + } + state = STATE_PREDEPLOYED; + session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); + return transformer; + } catch (RuntimeException ex) { + state = STATE_PREDEPLOY_FAILED; + session = null; + throw new PersistenceException(EntityManagerSetupException.predeployFailed(persistenceUnitInfo.getPersistenceUnitName(), ex)); } } *************** *** 937,942 **** --- 1011,1020 ---- } + public boolean isInitial() { + return state == STATE_INITIAL; + } + public boolean isPredeployed() { return state == STATE_PREDEPLOYED; } *************** *** 949,978 **** return state == STATE_UNDEPLOYED; } ! protected void cleanUpSessionManager() { ! deploymentCount--; ! if(deploymentCount > 0) { ! return; ! } ! state = STATE_UNDEPLOYED; ! removeSessionFromGlobalSessionManager(); } /** * Undeploy may be called several times, but only the call that decreases ! * deploymentCount to 0 disconnects the session and removes it from the session manager. ! * Note that the session is an attribute of this class, ! * and could be deployed again (after been undeployed to deploymentCount 0 and disconnected). */ public synchronized void undeploy() { ! if(state != STATE_DEPLOYED) { return; } ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount}); try { ! cleanUpSessionManager(); } finally { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount}); if(state == STATE_UNDEPLOYED) { session = null; } --- 1027,1072 ---- return state == STATE_UNDEPLOYED; } ! public boolean isPredeployFailed() { ! return state == STATE_PREDEPLOY_FAILED; ! } ! ! public boolean isDeployFailed() { ! return state == STATE_DEPLOY_FAILED; ! } ! ! public int getFactoryCount() { ! return factoryCount; ! } ! ! public boolean shouldRedeploy() { ! return state == STATE_UNDEPLOYED || state == STATE_PREDEPLOY_FAILED; } /** * Undeploy may be called several times, but only the call that decreases ! * factoryCount to 0 disconnects the session and removes it from the session manager. ! * This method and predeploy - the only methods altering factoryCount - should be synchronized. ! * After undeploy call that turns factoryCount to 0: ! * session==null; ! * PREDEPLOYED, DEPLOYED and DEPLOYED_FAILED states change to UNDEPLOYED state. */ public synchronized void undeploy() { ! if(state == STATE_INITIAL || state == STATE_PREDEPLOY_FAILED || state == STATE_UNDEPLOYED) { ! // must already have factoryCount==0 and session==null return; } ! // state is PREDEPLOYED, DEPLOYED or DEPLOY_FAILED ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); try { ! factoryCount--; ! if(factoryCount > 0) { ! return; ! } ! state = STATE_UNDEPLOYED; ! removeSessionFromGlobalSessionManager(); } finally { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); if(state == STATE_UNDEPLOYED) { session = null; } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/localization/i18n/TraceLocalizationResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000007/AB0952363AC40CBFE034080020E8C54E.10 Report generated at Fri Dec 15 17:18:58 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000007/AB0952363AC40CBFE034080020E8C54E.10 Fri Dec 15 16:58:45 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/localization/i18n/TraceLocalizationResource.java Fri Dec 15 17:18:57 2006 *************** *** 269,278 **** { "property_value_default", "property={0}; default value={1}"}, { "handler_property_value_specified", "property={0}; value={1}; translated value={2}"}, { "handler_property_value_default", "property={0}; default value={1}; translated value={2}"}, ! { "deploy_begin", "begin deploying Persistence Unit {0}; state {1}; deploymentCount {2}"}, ! { "deploy_end", "end deploying Persistence Unit {0}; state {1}; deploymentCount {2}"}, ! { "undeploy_begin", "begin undeploying Persistence Unit {0}; state {1}; deploymentCount {2}"}, ! { "undeploy_end", "end undeploying Persistence Unit {0}; state {1}; deploymentCount {2}"}, { "field_type_set_to_java_lang_string", "The default table generator could not locate or convert a java type ({1}) into a database type for database field ({0}). The generator uses 'java.lang.String' as default java type for the field." }, { "default_tables_created", "The table ({0}) is created."}, --- 269,280 ---- { "property_value_default", "property={0}; default value={1}"}, { "handler_property_value_specified", "property={0}; value={1}; translated value={2}"}, { "handler_property_value_default", "property={0}; default value={1}; translated value={2}"}, ! { "predeploy_begin", "begin predeploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "predeploy_end", "end predeploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "deploy_begin", "begin deploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "deploy_end", "end deploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "undeploy_begin", "begin undeploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "undeploy_end", "end undeploying Persistence Unit {0}; state {1}; factoryCount {2}"}, { "field_type_set_to_java_lang_string", "The default table generator could not locate or convert a java type ({1}) into a database type for database field ({0}). The generator uses 'java.lang.String' as default java type for the field." }, { "default_tables_created", "The table ({0}) is created."}, ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tltest/source/entity-persistence-tests/src/java/oracle/toplink/essentials/testing/tests/cmp3/advanced/EntityManagerJUnitTestSuite.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000001/AB0952363AC40CBFE034080020E8C54E.62 Report generated at Fri Dec 15 17:20:12 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000001/AB0952363AC40CBFE034080020E8C54E.62 Fri Dec 15 16:48:40 2006 --- /ade/ailitche_toplink_main/tltest/source/entity-persistence-tests/src/java/oracle/toplink/essentials/testing/tests/cmp3/advanced/EntityManagerJUnitTestSuite.java Fri Dec 15 17:18:57 2006 *************** *** 3690,3695 **** --- 3690,3718 ---- } } + // gf1732 + public void testMultipleEntityManagerFactories() { + // close the original factory + closeEntityManagerFactory(); + // create the new one - not yet deployed + EntityManagerFactory factory1 = getEntityManagerFactory(); + // create the second one + EntityManagerFactory factory2 = Persistence.createEntityManagerFactory("default", getDatabaseProperties()); + // deploy + factory2.createEntityManager(); + // close + factory2.close(); + + try { + // now try to getEM from the first one - this used to throw exception + factory1.createEntityManager(); + // don't close factory1 if all is well + } catch (PersistenceException ex) { + fail("factory1.createEM threw exception: " + ex.getMessage()); + factory1.close(); + } + } + public static void main(String[] args) { // Now run JUnit. junit.swingui.TestRunner.main(args); ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/ejb/cmp3/EntityManagerFactoryProvider.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000002/AB0952363AC40CBFE034080020E8C54E.53 Report generated at Fri Dec 15 17:20:12 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000002/AB0952363AC40CBFE034080020E8C54E.53 Fri Dec 15 16:53:31 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/ejb/cmp3/EntityManagerFactoryProvider.java Fri Dec 15 17:18:57 2006 *************** *** 122,141 **** if (emSetupImpl == null) { throw new PersistenceException(EntityManagerSetupException.puNotExist(name)); } ! if(emSetupImpl.isUndeployed()) { ! ((SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo()).setClassLoader(JavaSECMPInitializer.getMainLoader()); ! ((SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo()).setNewTempClassLoader(JavaSECMPInitializer.getMainLoader()); ! // the first parameter is ignored if predeploy called after undeploy emSetupImpl.predeploy(null, nonNullProperties); } ! EntityManagerFactoryImpl factory = new EntityManagerFactoryImpl(emSetupImpl, nonNullProperties); ! ! // This code has been added to allow validation to occur without actually calling createEntityManager ! if (emSetupImpl.shouldGetSessionOnCreateFactory(nonNullProperties)) { ! factory.getServerSession(); } - return factory; } /** --- 122,162 ---- if (emSetupImpl == null) { throw new PersistenceException(EntityManagerSetupException.puNotExist(name)); } ! ! // synchronized to prevent overriding of the class loader ! // and also calls to predeploy and undeploy by other threads - ! // the latter may alter result of shouldRedeploy method. ! synchronized(emSetupImpl) { ! if(emSetupImpl.shouldRedeploy()) { ! SEPersistenceUnitInfo persistenceInfo = (SEPersistenceUnitInfo)emSetupImpl.getPersistenceUnitInfo(); ! persistenceInfo.setClassLoader(JavaSECMPInitializer.getMainLoader()); ! persistenceInfo.setNewTempClassLoader(JavaSECMPInitializer.getMainLoader()); ! } ! // the first parameter is ignored - persistenceInfo has been already passed ! // when predeploy first called by JavaSECMPInitializer. ! // If shouldRedeploy is true, then predeploy creates a new session, ! // otherwise it only increments factoryCount. ! // emSetupImpl.predeploy(null, nonNullProperties); } ! EntityManagerFactoryImpl factory = null; ! try { ! factory = new EntityManagerFactoryImpl(emSetupImpl, nonNullProperties); ! ! // This code has been added to allow validation to occur without actually calling createEntityManager ! if (emSetupImpl.shouldGetSessionOnCreateFactory(nonNullProperties)) { ! factory.getServerSession(); ! } ! return factory; ! } catch (RuntimeException ex) { ! if(factory != null) { ! factory.close(); ! } else { ! emSetupImpl.undeploy(); ! } ! throw ex; } } /** ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/exceptions/EntityManagerSetupException.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.11 Report generated at Fri Dec 15 17:20:12 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000003/AB0952363AC40CBFE034080020E8C54E.11 Fri Dec 15 16:54:50 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/exceptions/EntityManagerSetupException.java Fri Dec 15 17:18:57 2006 *************** *** 40,45 **** --- 40,48 ---- public static final int FAILED_WHILE_PROCESSING_PROPERTY = 28014; public static final int FAILED_TO_INSTANTIATE_LOGGER = 28015; public static final int PU_NOT_EXIST = 28016; + public static final int CANNOT_PREDEPLOY = 28017; + public static final int PREDEPLOY_FAILED = 28018; + public static final int DEPLOY_FAILED = 28019; /** *************** *** 163,170 **** return setupException; } ! public static EntityManagerSetupException cannotDeployWithoutPredeploy(String persistenceUnitName) { ! Object[] args = { persistenceUnitName }; EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, CANNOT_DEPLOY_WITHOUT_PREDEPLOY, args)); setupException.setErrorCode(CANNOT_DEPLOY_WITHOUT_PREDEPLOY); --- 166,173 ---- return setupException; } ! public static EntityManagerSetupException cannotDeployWithoutPredeploy(String persistenceUnitName, String state) { ! Object[] args = { persistenceUnitName, state }; EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, CANNOT_DEPLOY_WITHOUT_PREDEPLOY, args)); setupException.setErrorCode(CANNOT_DEPLOY_WITHOUT_PREDEPLOY); *************** *** 194,197 **** --- 197,224 ---- setupException.setErrorCode(PU_NOT_EXIST); return setupException; } + + public static EntityManagerSetupException cannotPredeploy(String persistenceUnitName, String state) { + Object[] args = { persistenceUnitName, state }; + + EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, CANNOT_PREDEPLOY, args)); + setupException.setErrorCode(CANNOT_PREDEPLOY); + return setupException; + } + + public static EntityManagerSetupException predeployFailed(String persistenceUnitName, RuntimeException exception) { + Object[] args = { persistenceUnitName }; + + EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, PREDEPLOY_FAILED, args), exception); + setupException.setErrorCode(PREDEPLOY_FAILED); + return setupException; + } + + public static EntityManagerSetupException deployFailed(String persistenceUnitName, RuntimeException exception) { + Object[] args = { persistenceUnitName }; + + EntityManagerSetupException setupException = new EntityManagerSetupException(ExceptionMessageGenerator.buildMessage(EntityManagerSetupException.class, DEPLOY_FAILED, args), exception); + setupException.setErrorCode(DEPLOY_FAILED); + return setupException; + } } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/EntityManagerSetupExceptionResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000004/AB0952363AC40CBFE034080020E8C54E.15 Report generated at Fri Dec 15 17:20:12 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000004/AB0952363AC40CBFE034080020E8C54E.15 Fri Dec 15 16:55:12 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/exceptions/i18n/EntityManagerSetupExceptionResource.java Fri Dec 15 17:18:57 2006 *************** *** 43,52 **** { "28010", "PersistenceUnitInfo {0} has transactionType JTA, but doesn't have jtaDataSource." }, { "28011", "The session, [{0}], built for a persistence unit was not available at the time it was deployed. This means that somehow the session was removed from the container in the middle of the deployment process." }, { "28012", "Value [{0}] is of incorrect type for property [{2}], value type should be [{1}]." }, ! { "28013", "Attempted to deploy PersistenceUnit [{0}] for which predeploy method either had not called or had failed" }, { "28014", "Exception was thrown while processing property [{0}] with value {[1}]." }, { "28015", "Failed to instantiate SessionLog of type [{0}] specified in [{1}] property." }, ! { "28016", "The persistence unit with name [{0}] does not exist." } }; /** --- 43,55 ---- { "28010", "PersistenceUnitInfo {0} has transactionType JTA, but doesn't have jtaDataSource." }, { "28011", "The session, [{0}], built for a persistence unit was not available at the time it was deployed. This means that somehow the session was removed from the container in the middle of the deployment process." }, { "28012", "Value [{0}] is of incorrect type for property [{2}], value type should be [{1}]." }, ! { "28013", "Attempted to deploy PersistenceUnit [{0}] while being in the wrong state [{1}]. Close all factories for this PersistenceUnit." }, { "28014", "Exception was thrown while processing property [{0}] with value {[1}]." }, { "28015", "Failed to instantiate SessionLog of type [{0}] specified in [{1}] property." }, ! { "28016", "The persistence unit with name [{0}] does not exist." }, ! {"28017", "Attempted to predeploy PersistenceUnit [{0}] while being in the wrong state [{1}]." }, ! {"28018", "predeploy for PersistenceUnit [{0}] failed." }, ! {"28019", "deploy for PersistenceUnit [{0}] failed. Close all factories for this PersistenceUnit." } }; /** ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/base/EntityManagerFactoryImpl.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000005/AB0952363AC40CBFE034080020E8C54E.15 Report generated at Fri Dec 15 17:20:12 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000005/AB0952363AC40CBFE034080020E8C54E.15 Fri Dec 15 16:56:33 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/base/EntityManagerFactoryImpl.java Fri Dec 15 17:18:57 2006 *************** *** 89,97 **** public synchronized void close(){ verifyOpen(); isOpen = false; ! if(serverSession != null) { ! setupImpl.undeploy(); ! } } --- 89,95 ---- public synchronized void close(){ verifyOpen(); isOpen = false; ! setupImpl.undeploy(); } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/EntityManagerSetupImpl.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000006/AB0952363AC40CBFE034080020E8C54E.82 Report generated at Fri Dec 15 17:20:12 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000006/AB0952363AC40CBFE034080020E8C54E.82 Fri Dec 15 16:57:04 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/ejb/cmp3/EntityManagerSetupImpl.java Fri Dec 15 17:18:57 2006 *************** *** 37,43 **** import oracle.toplink.essentials.internal.weaving.TransformerFactory; import oracle.toplink.essentials.jndi.JNDIConnector; import oracle.toplink.essentials.logging.AbstractSessionLog; - import oracle.toplink.essentials.logging.DefaultSessionLog; import oracle.toplink.essentials.logging.SessionLog; import oracle.toplink.essentials.internal.security.PrivilegedAccessHelper; import oracle.toplink.essentials.internal.security.PrivilegedClassForName; --- 37,42 ---- *************** *** 52,58 **** import oracle.toplink.essentials.internal.ejb.cmp3.base.CMP3Policy; import oracle.toplink.essentials.platform.server.CustomServerPlatform; import oracle.toplink.essentials.platform.server.ServerPlatform; - import oracle.toplink.essentials.platform.server.NoServerPlatform; import oracle.toplink.essentials.exceptions.*; import oracle.toplink.essentials.internal.helper.EJB30ConversionManager; import javax.persistence.spi.PersistenceUnitTransactionType; --- 51,56 ---- *************** *** 80,101 **** protected MetadataProcessor processor = null; protected PersistenceUnitInfo persistenceUnitInfo = null; protected Map predeployProperties = null; ! // may be positive only in STATE_DEPLOYED ! protected int deploymentCount = 0; protected ServerSession session = null; protected boolean isInContainerMode = false; // indicates whether weaving was used on the first run through predeploy (in STATE_INITIAL) protected boolean enableLazyForOneToOne = false; protected SecurableObjectHolder securableObjectHolder = new SecurableObjectHolder(); ! public static final String STATE_INITIAL = "Initial"; ! public static final String STATE_PREDEPLOYED = "Predeployed"; ! public static final String STATE_DEPLOYED = "Deployed"; ! public static final String STATE_UNDEPLOYED = "Undeployed"; protected String state = STATE_INITIAL; ! public static final String ERROR_LOADING_XML_FILE = "error_loading_xml_file"; public static final String EXCEPTION_LOADING_ENTITY_CLASS = "exception_loading_entity_class"; /** --- 78,126 ---- protected MetadataProcessor processor = null; protected PersistenceUnitInfo persistenceUnitInfo = null; protected Map predeployProperties = null; ! // count a number of open factories that use this object. ! protected int factoryCount = 0; protected ServerSession session = null; + // true if predeploy called by createContainerEntityManagerFactory; false - createEntityManagerFactory protected boolean isInContainerMode = false; // indicates whether weaving was used on the first run through predeploy (in STATE_INITIAL) protected boolean enableLazyForOneToOne = false; protected SecurableObjectHolder securableObjectHolder = new SecurableObjectHolder(); ! // factoryCount==0; session==null ! public static final String STATE_INITIAL = "Initial"; ! ! // session != null ! public static final String STATE_PREDEPLOYED = "Predeployed"; ! ! // factoryCount>0; session != null; session stored in SessionManager ! public static final String STATE_DEPLOYED = "Deployed"; ! ! // factoryCount==0; session==null ! public static final String STATE_PREDEPLOY_FAILED="PredeployFailed"; ! ! // factoryCount>0; session != null ! public static final String STATE_DEPLOY_FAILED = "DeployFailed"; ! ! // factoryCount==0; session==null ! public static final String STATE_UNDEPLOYED = "Undeployed"; protected String state = STATE_INITIAL; ! /** ! * Initial -----> PredeployFailed ! * | | ! * V V ! * |-> Predeployed --> DeployFailed ! * | | | | ! * | V V V ! * | Deployed -> Undeployed-->| ! * | | ! * |<-------------------------V ! */ ! ! ! public static final String ERROR_LOADING_XML_FILE = "error_loading_xml_file"; public static final String EXCEPTION_LOADING_ENTITY_CLASS = "exception_loading_entity_class"; /** *************** *** 121,188 **** * the predeploy phase we were in a stage where we were not let allowed to load the real classes. * * Deploy could be called several times - but only the first call does the actual deploying - ! * additional calls allow to update session properties (provided the session is not connected) and ! * encrease deploymentCount (which decreased by calls to undeploy method). ! * * @param realClassLoader The class loader that was used to load the entity classes. This loader * will be maintained for the lifespan of the loaded classes. * @param additionalProperties added to predeployProperties for updateServerSession overriding existing properties. * In JSE case it allows to alter properties in main (as opposed to preMain where preDeploy is called). * @return An EntityManagerFactory to be used by the Container to obtain EntityManagers */ ! public synchronized ServerSession deploy(ClassLoader realClassLoader, Map additionalProperties) { if(state != STATE_PREDEPLOYED && state != STATE_DEPLOYED) { ! throw new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(persistenceUnitInfo.getPersistenceUnitName())); } ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount}); try { Map deployProperties = mergeMaps(additionalProperties, predeployProperties); translateOldProperties(deployProperties, session); if(state == STATE_PREDEPLOYED) { ! // The project is initially created using class names rather than classes. This call will make the conversion ! session.getProject().convertClassNamesToClasses(realClassLoader); ! ! // listeners and queries require the real classes and are therefore built during deploy using the realClassLoader ! processor.setClassLoader(realClassLoader); ! processor.addEntityListeners(); ! processor.addNamedQueries(); ! // free the resouces that we don't need any more. ! processor.cleanup(); ! processor = null; ! ! initServerSession(deployProperties); ! ! if (session.getIntegrityChecker().hasErrors()){ ! session.handleException(new IntegrityException(session.getIntegrityChecker())); } - - session.getDatasourcePlatform().getConversionManager().setLoader(realClassLoader); } ! deploymentCount++; ! state = STATE_DEPLOYED; ! try{ ! updateServerSession(deployProperties); ! if(!session.isConnected()) { ! if(isValidationOnly(deployProperties, false)) { ! session.initializeDescriptors(); ! } else { ! login(session, deployProperties); ! generateDDLFiles(session, deployProperties, !isInContainerMode); } } - } catch (RuntimeException exception) { - cleanUpSessionManager(); - throw exception; } return session; } catch (oracle.toplink.essentials.exceptions.ValidationException exception) { throw new javax.persistence.PersistenceException(exception); } finally { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount}); ! if(state == STATE_UNDEPLOYED) { ! session = null; ! } } } --- 146,225 ---- * the predeploy phase we were in a stage where we were not let allowed to load the real classes. * * Deploy could be called several times - but only the first call does the actual deploying - ! * additional calls allow to update session properties (in case the session is not connected). ! * ! * Note that there is no need to synchronize deploy method - it doesn't alter factoryCount ! * and while deploy is executed no other method can alter the current state ! * (predeploy call would just increment factoryCount; undeploy call would not drop factoryCount to 0). ! * However precautions should be taken to handle concurrent calls to deploy, because those may ! * alter the current state or connect the session. ! * * @param realClassLoader The class loader that was used to load the entity classes. This loader * will be maintained for the lifespan of the loaded classes. * @param additionalProperties added to predeployProperties for updateServerSession overriding existing properties. * In JSE case it allows to alter properties in main (as opposed to preMain where preDeploy is called). * @return An EntityManagerFactory to be used by the Container to obtain EntityManagers */ ! public ServerSession deploy(ClassLoader realClassLoader, Map additionalProperties) { if(state != STATE_PREDEPLOYED && state != STATE_DEPLOYED) { ! throw new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(persistenceUnitInfo.getPersistenceUnitName(), state)); } ! // state is PREDEPLOYED or DEPLOYED ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); try { Map deployProperties = mergeMaps(additionalProperties, predeployProperties); translateOldProperties(deployProperties, session); if(state == STATE_PREDEPLOYED) { ! synchronized(session) { ! if(state == STATE_PREDEPLOYED) { ! try { ! // The project is initially created using class names rather than classes. This call will make the conversion ! session.getProject().convertClassNamesToClasses(realClassLoader); ! ! // listeners and queries require the real classes and are therefore built during deploy using the realClassLoader ! processor.setClassLoader(realClassLoader); ! processor.addEntityListeners(); ! processor.addNamedQueries(); ! // free the resouces that we don't need any more. ! processor.cleanup(); ! processor = null; ! ! initServerSession(deployProperties); ! ! if (session.getIntegrityChecker().hasErrors()){ ! session.handleException(new IntegrityException(session.getIntegrityChecker())); ! } ! ! session.getDatasourcePlatform().getConversionManager().setLoader(realClassLoader); ! state = STATE_DEPLOYED; ! } catch (RuntimeException ex) { ! state = STATE_DEPLOY_FAILED; ! // session not discarded here only because it will be used in undeploy method for debug logging. ! throw new PersistenceException(EntityManagerSetupException.deployFailed(persistenceUnitInfo.getPersistenceUnitName(), ex)); ! } ! } } } ! // state is DEPLOYED ! if(!session.isConnected()) { ! synchronized(session) { ! if(!session.isConnected()) { ! updateServerSession(deployProperties); ! if(isValidationOnly(deployProperties, false)) { ! session.initializeDescriptors(); ! } else { ! login(session, deployProperties); ! generateDDLFiles(session, deployProperties, !isInContainerMode); ! } } } } return session; } catch (oracle.toplink.essentials.exceptions.ValidationException exception) { throw new javax.persistence.PersistenceException(exception); } finally { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "deploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); } } *************** *** 459,537 **** /** * Perform any steps necessary prior to actual deployment. This includes any steps in the session * creation that do not require the real loaded domain classes. * * @return A transformer (which may be null) that should be plugged into the proper * classloader to allow classes to be transformed as they get loaded. * @see #predeploy(javax.persistence.spi.PersistenceUnitInfo, java.util.Map) */ ! public ClassTransformer predeploy(PersistenceUnitInfo info, Map extendedProperties) { ! if(state == STATE_INITIAL) { persistenceUnitInfo = info; } ! ClassLoader privateClassLoader = persistenceUnitInfo.getNewTempClassLoader(); ! predeployProperties = mergeMaps(extendedProperties, persistenceUnitInfo.getProperties()); ! ! // translate old properties ! // this should be done before using properties (i.e. ServerPlatform) ! translateOldProperties(predeployProperties, null); ! ! // create server session (it should be done before initializing ServerPlatform) ! session = new ServerSession(new Project(new DatabaseLogin())); ! ! // ServerSession name and ServerPlatform must be set prior to setting the loggers. ! setServerSessionName(predeployProperties); ! updateServerPlatform(predeployProperties); ! // Update loggers and settings for the singleton logger and the session logger. ! updateLoggers(predeployProperties, true, false); ! warnOldProperties(predeployProperties, session); ! ! session.getPlatform().setConversionManager(new EJB30ConversionManager()); ! if(!isValidationOnly(predeployProperties, false) && persistenceUnitInfo != null && persistenceUnitInfo.getTransactionType() == PersistenceUnitTransactionType.JTA) { ! if(persistenceUnitInfo.getJtaDataSource() == null) { ! throw new PersistenceException(EntityManagerSetupException.jtaPersistenceUnitInfoMissingJtaDataSource(persistenceUnitInfo.getPersistenceUnitName())); } ! } ! ! // this flag is used to disable work done as a result of the LAZY hint on OneToOne mappings ! if(state == STATE_INITIAL ) { ! enableLazyForOneToOne = true; ! String weaving = getConfigPropertyAsString(TopLinkProperties.WEAVING); ! if (weaving != null && weaving.equalsIgnoreCase("false")) { ! enableLazyForOneToOne = false; } } - - boolean throwExceptionOnFail = "true".equalsIgnoreCase( - EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(EntityManagerFactoryProvider.TOPLINK_ORM_THROW_EXCEPTIONS, predeployProperties, "true", session)); - - // Create an instance of MetadataProcessor for specified persistence unit info - processor = new MetadataProcessor(persistenceUnitInfo, session, privateClassLoader, enableLazyForOneToOne); - - // Process the Object/relational metadata from XML and annotations. - PersistenceUnitProcessor.processORMetadata(processor,privateClassLoader, session,throwExceptionOnFail); - - - // The connector will be reconstructed when the session is actually deployed - session.getProject().getLogin().setConnector(new DefaultConnector()); - - if (session.getIntegrityChecker().hasErrors()){ - session.handleException(new IntegrityException(session.getIntegrityChecker())); - } - - // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings. It will only - // be returned if we we are mean to process these mappings - ClassTransformer transformer = null; - if (enableLazyForOneToOne){ - // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use - Collection entities = PersistenceUnitProcessor.buildEntityList(processor,privateClassLoader); - transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); - } - - state = STATE_PREDEPLOYED; - return transformer; } --- 496,611 ---- /** * Perform any steps necessary prior to actual deployment. This includes any steps in the session * creation that do not require the real loaded domain classes. + * + * The first call to this method caches persistenceUnitInfo which is reused in the following calls. + * + * Note that in JSE case factoryCount is NOT incremented on the very first call + * (by JavaSECMPInitializer.callPredeploy, typically in preMain). + * That provides 1 to 1 correspondence between factoryCount and the number of open factories. + * + * In case factoryCount > 0 the method just increments factoryCount. + * factory == 0 triggers creation of a new session. + * + * This method and undeploy - the only methods altering factoryCount - should be synchronized. * * @return A transformer (which may be null) that should be plugged into the proper * classloader to allow classes to be transformed as they get loaded. * @see #predeploy(javax.persistence.spi.PersistenceUnitInfo, java.util.Map) */ ! public synchronized ClassTransformer predeploy(PersistenceUnitInfo info, Map extendedProperties) { ! if(state == STATE_DEPLOY_FAILED) { ! throw new PersistenceException(EntityManagerSetupException.cannotPredeploy(persistenceUnitInfo.getPersistenceUnitName(), state)); ! } ! if(state == STATE_PREDEPLOYED || state == STATE_DEPLOYED) { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "predeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); ! factoryCount++; ! if(session != null) { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); ! } ! return null; ! } else if(state == STATE_INITIAL) { persistenceUnitInfo = info; } ! // state is INITIAL, PREDEPLOY_FAILED or UNDEPLOYED ! try { ! ClassLoader privateClassLoader = persistenceUnitInfo.getNewTempClassLoader(); ! // create server session (it should be done before initializing ServerPlatform) ! // (also before translateOldProperties - it requires session to log warnings) ! session = new ServerSession(new Project(new DatabaseLogin())); ! ! predeployProperties = mergeMaps(extendedProperties, persistenceUnitInfo.getProperties()); ! ! // translate old properties ! // this should be done before using properties (i.e. ServerPlatform) ! translateOldProperties(predeployProperties, null); ! ! // ServerSession name and ServerPlatform must be set prior to setting the loggers. ! setServerSessionName(predeployProperties); ! updateServerPlatform(predeployProperties); ! ! // Update loggers and settings for the singleton logger and the session logger. ! updateLoggers(predeployProperties, true, false); ! ! warnOldProperties(predeployProperties, session); ! ! session.getPlatform().setConversionManager(new EJB30ConversionManager()); ! if(!isValidationOnly(predeployProperties, false) && persistenceUnitInfo != null && persistenceUnitInfo.getTransactionType() == PersistenceUnitTransactionType.JTA) { ! if(persistenceUnitInfo.getJtaDataSource() == null) { ! throw new PersistenceException(EntityManagerSetupException.jtaPersistenceUnitInfoMissingJtaDataSource(persistenceUnitInfo.getPersistenceUnitName())); ! } ! } ! ! // this flag is used to disable work done as a result of the LAZY hint on OneToOne mappings ! if(state == STATE_INITIAL ) { ! enableLazyForOneToOne = true; ! String weaving = getConfigPropertyAsString(TopLinkProperties.WEAVING); ! if (weaving != null && weaving.equalsIgnoreCase("false")) { ! enableLazyForOneToOne = false; ! } ! } ! ! boolean throwExceptionOnFail = "true".equalsIgnoreCase( ! EntityManagerFactoryProvider.getConfigPropertyAsStringLogDebug(EntityManagerFactoryProvider.TOPLINK_ORM_THROW_EXCEPTIONS, predeployProperties, "true", session)); ! ! // Create an instance of MetadataProcessor for specified persistence unit info ! processor = new MetadataProcessor(persistenceUnitInfo, session, privateClassLoader, enableLazyForOneToOne); ! ! // Process the Object/relational metadata from XML and annotations. ! PersistenceUnitProcessor.processORMetadata(processor,privateClassLoader, session,throwExceptionOnFail); ! ! ! // The connector will be reconstructed when the session is actually deployed ! session.getProject().getLogin().setConnector(new DefaultConnector()); ! if (session.getIntegrityChecker().hasErrors()){ ! session.handleException(new IntegrityException(session.getIntegrityChecker())); } ! ! // The transformer is capable of altering domain classes to handle a LAZY hint for OneToOne mappings. It will only ! // be returned if we we are mean to process these mappings ! ClassTransformer transformer = null; ! if (enableLazyForOneToOne){ ! // build a list of entities the persistence unit represented by this EntityManagerSetupImpl will use ! Collection entities = PersistenceUnitProcessor.buildEntityList(processor,privateClassLoader); ! transformer = TransformerFactory.createTransformerAndModifyProject(session, entities, privateClassLoader); } + + // factoryCount is not incremented only in case of a first call to preDeploy + // in non-container mode: this call is not associated with a factory + // but rather done by JavaSECMPInitializer.callPredeploy (typically in preMain). + if(state != STATE_INITIAL || this.isInContainerMode()) { + factoryCount++; + } + state = STATE_PREDEPLOYED; + session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "predeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); + return transformer; + } catch (RuntimeException ex) { + state = STATE_PREDEPLOY_FAILED; + session = null; + throw new PersistenceException(EntityManagerSetupException.predeployFailed(persistenceUnitInfo.getPersistenceUnitName(), ex)); } } *************** *** 937,942 **** --- 1011,1020 ---- } + public boolean isInitial() { + return state == STATE_INITIAL; + } + public boolean isPredeployed() { return state == STATE_PREDEPLOYED; } *************** *** 949,978 **** return state == STATE_UNDEPLOYED; } ! protected void cleanUpSessionManager() { ! deploymentCount--; ! if(deploymentCount > 0) { ! return; ! } ! state = STATE_UNDEPLOYED; ! removeSessionFromGlobalSessionManager(); } /** * Undeploy may be called several times, but only the call that decreases ! * deploymentCount to 0 disconnects the session and removes it from the session manager. ! * Note that the session is an attribute of this class, ! * and could be deployed again (after been undeployed to deploymentCount 0 and disconnected). */ public synchronized void undeploy() { ! if(state != STATE_DEPLOYED) { return; } ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount}); try { ! cleanUpSessionManager(); } finally { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, deploymentCount}); if(state == STATE_UNDEPLOYED) { session = null; } --- 1027,1072 ---- return state == STATE_UNDEPLOYED; } ! public boolean isPredeployFailed() { ! return state == STATE_PREDEPLOY_FAILED; ! } ! ! public boolean isDeployFailed() { ! return state == STATE_DEPLOY_FAILED; ! } ! ! public int getFactoryCount() { ! return factoryCount; ! } ! ! public boolean shouldRedeploy() { ! return state == STATE_UNDEPLOYED || state == STATE_PREDEPLOY_FAILED; } /** * Undeploy may be called several times, but only the call that decreases ! * factoryCount to 0 disconnects the session and removes it from the session manager. ! * This method and predeploy - the only methods altering factoryCount - should be synchronized. ! * After undeploy call that turns factoryCount to 0: ! * session==null; ! * PREDEPLOYED, DEPLOYED and DEPLOYED_FAILED states change to UNDEPLOYED state. */ public synchronized void undeploy() { ! if(state == STATE_INITIAL || state == STATE_PREDEPLOY_FAILED || state == STATE_UNDEPLOYED) { ! // must already have factoryCount==0 and session==null return; } ! // state is PREDEPLOYED, DEPLOYED or DEPLOY_FAILED ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_begin", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); try { ! factoryCount--; ! if(factoryCount > 0) { ! return; ! } ! state = STATE_UNDEPLOYED; ! removeSessionFromGlobalSessionManager(); } finally { ! session.log(SessionLog.FINEST, SessionLog.PROPERTIES, "undeploy_end", new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(), state, factoryCount}); if(state == STATE_UNDEPLOYED) { session = null; } ================================================================================ Merge Diffs: /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/localization/i18n/TraceLocalizationResource.java vs. /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000007/AB0952363AC40CBFE034080020E8C54E.10 Report generated at Fri Dec 15 17:20:12 2006 -------------------------------------------------------------------------------- *** /net/stottnfs2.ca.oracle.com/vol/vol1/ade_ottawa_txn/ailitche/ailitche_ri_gf1732_061215/ade_storage/000007/AB0952363AC40CBFE034080020E8C54E.10 Fri Dec 15 16:58:45 2006 --- /ade/ailitche_toplink_main/tldev/source/essentials/oracle/toplink/essentials/internal/localization/i18n/TraceLocalizationResource.java Fri Dec 15 17:18:57 2006 *************** *** 269,278 **** { "property_value_default", "property={0}; default value={1}"}, { "handler_property_value_specified", "property={0}; value={1}; translated value={2}"}, { "handler_property_value_default", "property={0}; default value={1}; translated value={2}"}, ! { "deploy_begin", "begin deploying Persistence Unit {0}; state {1}; deploymentCount {2}"}, ! { "deploy_end", "end deploying Persistence Unit {0}; state {1}; deploymentCount {2}"}, ! { "undeploy_begin", "begin undeploying Persistence Unit {0}; state {1}; deploymentCount {2}"}, ! { "undeploy_end", "end undeploying Persistence Unit {0}; state {1}; deploymentCount {2}"}, { "field_type_set_to_java_lang_string", "The default table generator could not locate or convert a java type ({1}) into a database type for database field ({0}). The generator uses 'java.lang.String' as default java type for the field." }, { "default_tables_created", "The table ({0}) is created."}, --- 269,280 ---- { "property_value_default", "property={0}; default value={1}"}, { "handler_property_value_specified", "property={0}; value={1}; translated value={2}"}, { "handler_property_value_default", "property={0}; default value={1}; translated value={2}"}, ! { "predeploy_begin", "begin predeploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "predeploy_end", "end predeploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "deploy_begin", "begin deploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "deploy_end", "end deploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "undeploy_begin", "begin undeploying Persistence Unit {0}; state {1}; factoryCount {2}"}, ! { "undeploy_end", "end undeploying Persistence Unit {0}; state {1}; factoryCount {2}"}, { "field_type_set_to_java_lang_string", "The default table generator could not locate or convert a java type ({1}) into a database type for database field ({0}). The generator uses 'java.lang.String' as default java type for the field." }, { "default_tables_created", "The table ({0}) is created."},