From: <hib...@li...> - 2006-03-10 18:14:29
|
Author: ste...@jb... Date: 2006-03-10 13:14:21 -0500 (Fri, 10 Mar 2006) New Revision: 9595 Added: trunk/Hibernate3/test/org/hibernate/test/connections/Other.java Modified: trunk/Hibernate3/src/org/hibernate/Transaction.java trunk/Hibernate3/src/org/hibernate/engine/SessionImplementor.java trunk/Hibernate3/src/org/hibernate/event/def/AbstractFlushingEventListener.java trunk/Hibernate3/src/org/hibernate/jdbc/ConnectionManager.java trunk/Hibernate3/src/org/hibernate/jdbc/JDBCContext.java trunk/Hibernate3/src/org/hibernate/transaction/CMTTransaction.java trunk/Hibernate3/src/org/hibernate/transaction/CMTTransactionFactory.java trunk/Hibernate3/src/org/hibernate/transaction/JDBCTransaction.java trunk/Hibernate3/src/org/hibernate/transaction/JDBCTransactionFactory.java trunk/Hibernate3/src/org/hibernate/transaction/JTATransaction.java trunk/Hibernate3/src/org/hibernate/transaction/JTATransactionFactory.java trunk/Hibernate3/src/org/hibernate/transaction/TransactionFactory.java trunk/Hibernate3/src/org/hibernate/util/JTAHelper.java trunk/Hibernate3/test/org/hibernate/test/connections/AggressiveReleaseTest.java trunk/Hibernate3/test/org/hibernate/test/connections/BasicConnectionProviderTest.java trunk/Hibernate3/test/org/hibernate/test/connections/ConnectionManagementTestCase.java trunk/Hibernate3/test/org/hibernate/test/connections/CurrentSessionConnectionTest.java trunk/Hibernate3/test/org/hibernate/test/connections/Silly.hbm.xml trunk/Hibernate3/test/org/hibernate/test/connections/Silly.java trunk/Hibernate3/test/org/hibernate/test/connections/SuppliedConnectionTest.java trunk/Hibernate3/test/org/hibernate/test/connections/ThreadLocalCurrentSessionTest.java trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java trunk/Hibernate3/test/org/hibernate/test/tm/CMTTest.java Log: HHH-1555 : maintain connections during flush even with aggressive release; HHH-1559 : facilitate EJB3 joinTransaction; test suite cleanup Modified: trunk/Hibernate3/src/org/hibernate/Transaction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/Transaction.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/Transaction.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -31,9 +31,11 @@ public void begin() throws HibernateException; /** - * Flush the associated <tt>Session</tt> and end the unit of work. + * Flush the associated <tt>Session</tt> and end the unit of work (unless + * we are in {@link FlushMode#NEVER}. + * </p> * This method will commit the underlying transaction if and only - * if the transaction was initiated by this object. + * if the underlying transaction was initiated by this object. * * @throws HibernateException */ @@ -48,37 +50,56 @@ /** * Was this transaction rolled back or set to rollback only? + * <p/> + * This only accounts for actions initiated from this local transaction. + * If, for example, the underlying transaction is forced to rollback via + * some other means, this method still reports false because the rollback + * was not initiated from here. * - * @return boolean + * @return boolean True if the transaction was rolled back via this + * local transaction; false otherwise. * @throws HibernateException */ public boolean wasRolledBack() throws HibernateException; /** - * Check if this transaction was successfully committed. This method - * could return <tt>false</tt> even after successful invocation - * of <tt>commit()</tt>. + * Check if this transaction was successfully committed. + * <p/> + * This method could return <tt>false</tt> even after successful invocation + * of {@link #commit}. As an example, JTA based strategies no-op on + * {@link #commit} calls if they did not start the transaction; in that case, + * they also report {@link #wasCommitted} as false. * - * @return boolean + * @return boolean True if the transaction was (unequivocally) committed + * via this local transaction; false otherwise. * @throws HibernateException */ public boolean wasCommitted() throws HibernateException; /** * Is this transaction still active? - * @return boolean + * <p/> + * Again, this only returns information in relation to the + * local transaction, not the actual underlying transaction. + * + * @return boolean Treu if this local transaction is still active. */ public boolean isActive() throws HibernateException; - + /** - * Register a user synchronization callback for this transaction + * Register a user synchronization callback for this transaction. + * + * @param synchronization The Synchronization callback to register. + * @throws HibernateException */ public void registerSynchronization(Synchronization synchronization) throws HibernateException; - + /** * Set the transaction timeout for any transaction started by * a subsequent call to <tt>begin()</tt> on this instance. + * + * @param seconds The number of seconds before a timeout. */ public void setTimeout(int seconds); } Modified: trunk/Hibernate3/src/org/hibernate/engine/SessionImplementor.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/engine/SessionImplementor.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/engine/SessionImplementor.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -284,4 +284,14 @@ public String getFetchProfile(); public JDBCContext getJDBCContext(); + + /** + * Determine whether the session is closed. Provided seperately from + * {@link #isOpen()} as this method does not attempt any JTA synch + * registration, where as {@link #isOpen()} does; which makes this one + * nicer to use for most internal purposes. + * + * @return True if the session is closed; false otherwise. + */ + public boolean isClosed(); } Modified: trunk/Hibernate3/src/org/hibernate/event/def/AbstractFlushingEventListener.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/event/def/AbstractFlushingEventListener.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/event/def/AbstractFlushingEventListener.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -289,6 +289,7 @@ log.trace("executing flush"); try { + session.getJDBCContext().getConnectionManager().flushBeginning(); // we need to lock the collection caches before // executing entity inserts/updates in order to // account for bidi associations @@ -299,6 +300,9 @@ log.error("Could not synchronize database state with session", he); throw he; } + finally { + session.getJDBCContext().getConnectionManager().flushEnding(); + } } Modified: trunk/Hibernate3/src/org/hibernate/jdbc/ConnectionManager.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/jdbc/ConnectionManager.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/jdbc/ConnectionManager.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -46,6 +46,7 @@ private transient Batcher batcher; private transient Interceptor interceptor; private boolean isClosed; + private transient boolean isFlushing; /** * Constructs a ConnectionManager. @@ -261,7 +262,10 @@ */ public void afterStatement() { if ( isAggressiveRelease() ) { - if ( batcher.hasOpenResources() ) { + if ( isFlushing ) { + log.debug( "skipping aggressive-release due to flush cycle" ); + } + else if ( batcher.hasOpenResources() ) { log.debug( "skipping aggresive-release due to open resources on batcher" ); } else if ( borrowedConnection != null ) { @@ -450,6 +454,26 @@ } } + /** + * Callback to let us know that a flush is beginning. We use this fact + * to temporarily circumvent aggressive connection releasing until after + * the flush cycle is complete {@link #flushEnding()} + */ + public void flushBeginning() { + log.trace( "registering flush begin" ); + isFlushing = true; + } + + /** + * Callback to let us know that a flush is ending. We use this fact to + * stop circumventing aggressive releasing connections. + */ + public void flushEnding() { + log.trace( "registering flush end" ); + isFlushing = false; + afterStatement(); + } + public boolean isReadyForSerialization() { return wasConnectionSupplied ? connection == null : !batcher.hasOpenResources(); } Modified: trunk/Hibernate3/src/org/hibernate/jdbc/JDBCContext.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/jdbc/JDBCContext.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/jdbc/JDBCContext.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -22,7 +22,6 @@ import org.hibernate.exception.JDBCExceptionHelper; import org.hibernate.transaction.CacheSynchronization; import org.hibernate.transaction.TransactionFactory; -import org.hibernate.util.JTAHelper; /** * Acts as the mediary between "entity-mode related" sessions in terms of @@ -87,15 +86,6 @@ // ConnectionManager.Callback implementation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ public void connectionOpened() { - if ( !isTransactionCallbackRegistered ) { - // If there is no current transaction callback registered - // when we obtain a connection, try to register one now. - // Note that this is not going to handle the case of - // multiple-transactions-per-connection when the user is - // manipulating transactions (need to use Hibernate txn) - registerSynchronizationIfPossible(); - } - if ( owner.getFactory().getStatistics().isStatisticsEnabled() ) { owner.getFactory().getStatisticsImplementor().connect(); } @@ -140,25 +130,46 @@ } public boolean registerSynchronizationIfPossible() { - if ( isTransactionCallbackRegistered ) return true; + if ( isTransactionCallbackRegistered ) { + // we already have a callback registered; either a local + // (org.hibernate.Transaction) transaction has accepted + // callback responsibilities, or we have previously + // registered a transaction synch. + return true; + } + boolean localCallbacksOnly = owner.getFactory().getSettings() + .getTransactionFactory() + .areCallbacksLocalToHibernateTransactions(); + if ( localCallbacksOnly ) { + // the configured transaction-factory says it only supports + // local callback mode, so no sense attempting to register a + // JTA Synchronization + return false; + } TransactionManager tm = owner.getFactory().getTransactionManager(); if ( tm == null ) { + // if there is no TM configured, we will not be able to access + // the javax.transaction.Transaction object in order to + // register a synch anyway. return false; } else { try { - javax.transaction.Transaction tx = tm.getTransaction(); - if ( JTAHelper.isTransactionInProgress(tx) ) { + if ( !isTransactionInProgress() ) { + log.debug( "TransactionFactory reported no active transaction; Synchronization not registered" ); + return false; + } + else { + javax.transaction.Transaction tx = tm.getTransaction(); tx.registerSynchronization( new CacheSynchronization(owner, this, tx, null) ); isTransactionCallbackRegistered = true; log.debug("successfully registered Synchronization"); return true; } - else { - log.debug("no active transaction, could not register Synchronization"); - return false; - } } + catch( HibernateException e ) { + throw e; + } catch (Exception e) { throw new TransactionException( "could not register synchronization with JTA TransactionManager", e ); } @@ -166,9 +177,8 @@ } public boolean isTransactionInProgress() { - boolean isHibernateTransactionActive = hibernateTransaction!=null && - hibernateTransaction.isActive(); - return isHibernateTransactionActive || JTAHelper.isTransactionInProgress( owner.getFactory() ); + return owner.getFactory().getSettings().getTransactionFactory() + .isTransactionInProgress( this, owner, hibernateTransaction ); } public Transaction getTransaction() throws HibernateException { @@ -268,10 +278,6 @@ * @throws IOException */ public void serialize(ObjectOutputStream oos) throws IOException { - boolean deserHasCallbackRegistered = isTransactionCallbackRegistered - && ! owner.getFactory().getSettings().getTransactionFactory() - .areCallbacksLocalToHibernateTransactions(); - oos.writeBoolean( deserHasCallbackRegistered ); connectionManager.serialize( oos ); } @@ -288,7 +294,6 @@ Interceptor interceptor) throws IOException { JDBCContext jdbcContext = new JDBCContext(); jdbcContext.owner = context; - jdbcContext.isTransactionCallbackRegistered = ois.readBoolean(); jdbcContext.connectionManager = ConnectionManager.deserialize( ois, context.getFactory(), Modified: trunk/Hibernate3/src/org/hibernate/transaction/CMTTransaction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/transaction/CMTTransaction.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/transaction/CMTTransaction.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -63,7 +63,7 @@ if (flush) { transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback() } - + begun = false; } @@ -72,7 +72,7 @@ if (!begun) { throw new TransactionException("Transaction not successfully started"); } - + log.debug("rollback"); try { @@ -82,7 +82,7 @@ log.error("Could not set transaction to rollback only", se); throw new TransactionException("Could not set transaction to rollback only", se); } - + begun = false; } Modified: trunk/Hibernate3/src/org/hibernate/transaction/CMTTransactionFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/transaction/CMTTransactionFactory.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/transaction/CMTTransactionFactory.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -6,8 +6,12 @@ import org.hibernate.ConnectionReleaseMode; import org.hibernate.HibernateException; import org.hibernate.Transaction; +import org.hibernate.TransactionException; +import org.hibernate.util.JTAHelper; import org.hibernate.jdbc.JDBCContext; +import javax.transaction.SystemException; + /** * Factory for <tt>CMTTransaction</tt>. * @@ -22,7 +26,7 @@ public void configure(Properties props) throws HibernateException {} - public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext) + public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext) throws HibernateException { return new CMTTransaction(jdbcContext, transactionContext); } @@ -35,4 +39,19 @@ return false; } + public boolean isTransactionInProgress( + JDBCContext jdbcContext, + Context transactionContext, + Transaction transaction) { + try { + return JTAHelper.isTransactionInProgress( + transactionContext.getFactory().getTransactionManager().getTransaction() + ); + } + catch( SystemException se ) { + throw new TransactionException( "Unable to check transaction status", se ); + } + + } + } Modified: trunk/Hibernate3/src/org/hibernate/transaction/JDBCTransaction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/transaction/JDBCTransaction.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/transaction/JDBCTransaction.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -50,9 +50,9 @@ if (commitFailed) { throw new TransactionException("cannot re-start transaction after failed commit"); } - - log.debug("begin"); + log.debug("begin"); + try { toggleAutoCommit = jdbcContext.connection().getAutoCommit(); if ( log.isDebugEnabled() ) { @@ -73,16 +73,16 @@ begun = true; committed = false; rolledBack = false; - + if ( timeout>0 ) { jdbcContext.getConnectionManager() .getBatcher() .setTransactionTimeout(timeout); } - + jdbcContext.afterTransactionBegin(this); } - + private void closeIfRequired() throws HibernateException { if ( callback && transactionContext.shouldAutoClose() && !transactionContext.isClosed() ) { try { @@ -106,7 +106,7 @@ transactionContext.managedFlush(); //if an exception occurs during flush, user must call rollback() } - beforeTransactionCompletion(); + notifyLocalSynchsBeforeTransactionCompletion(); if ( callback ) { jdbcContext.beforeTransactionCompletion( this ); } @@ -118,7 +118,7 @@ if ( callback ) { jdbcContext.afterTransactionCompletion( true, this ); } - afterTransactionCompletion( Status.STATUS_COMMITTED ); + notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_COMMITTED ); } catch (SQLException e) { log.error("JDBC commit failed", e); @@ -126,7 +126,7 @@ if ( callback ) { jdbcContext.afterTransactionCompletion( false, this ); } - afterTransactionCompletion( Status.STATUS_UNKNOWN ); + notifyLocalSynchsAfterTransactionCompletion( Status.STATUS_UNKNOWN ); throw new TransactionException("JDBC commit failed", e); } finally { @@ -153,20 +153,20 @@ if (!commitFailed) { - /*beforeTransactionCompletion(); + /*notifyLocalSynchsBeforeTransactionCompletion(); if ( callback ) { - jdbcContext.beforeTransactionCompletion( this ); + jdbcContext.notifyLocalSynchsBeforeTransactionCompletion( this ); }*/ try { rollbackAndResetAutoCommit(); log.debug("rolled back JDBC Connection"); rolledBack = true; - afterTransactionCompletion(Status.STATUS_ROLLEDBACK); + notifyLocalSynchsAfterTransactionCompletion(Status.STATUS_ROLLEDBACK); } catch (SQLException e) { log.error("JDBC rollback failed", e); - afterTransactionCompletion(Status.STATUS_UNKNOWN); + notifyLocalSynchsAfterTransactionCompletion(Status.STATUS_UNKNOWN); throw new TransactionException("JDBC rollback failed", e); } finally { @@ -203,15 +203,15 @@ public boolean wasRolledBack() { return rolledBack; } - + public boolean wasCommitted() { return committed; } public boolean isActive() { return begun && ! ( rolledBack || committed | commitFailed ); - } - + } + public void registerSynchronization(Synchronization sync) throws HibernateException { if (sync==null) throw new NullPointerException("null Synchronization"); if (synchronizations==null) { @@ -219,8 +219,8 @@ } synchronizations.add(sync); } - - private void beforeTransactionCompletion() { + + private void notifyLocalSynchsBeforeTransactionCompletion() { if (synchronizations!=null) { for ( int i=0; i<synchronizations.size(); i++ ) { Synchronization sync = (Synchronization) synchronizations.get(i); @@ -234,7 +234,7 @@ } } - private void afterTransactionCompletion(int status) { + private void notifyLocalSynchsAfterTransactionCompletion(int status) { begun = false; if (synchronizations!=null) { for ( int i=0; i<synchronizations.size(); i++ ) { Modified: trunk/Hibernate3/src/org/hibernate/transaction/JDBCTransactionFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/transaction/JDBCTransactionFactory.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/transaction/JDBCTransactionFactory.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -2,6 +2,7 @@ package org.hibernate.transaction; import java.util.Properties; +import java.sql.SQLException; import org.hibernate.ConnectionReleaseMode; import org.hibernate.Transaction; @@ -19,7 +20,7 @@ return ConnectionReleaseMode.AFTER_TRANSACTION; } - public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext) + public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext) throws HibernateException { return new JDBCTransaction( jdbcContext, transactionContext ); } @@ -34,4 +35,22 @@ return true; } + public boolean isTransactionInProgress( + JDBCContext jdbcContext, + Context transactionContext, + Transaction transaction) { +// try { +// // for JDBC-based transactions, we only want to return true +// // here if we (this transaction) are managing the transaction +// return transaction != null && +// transaction.isActive() && +// !jdbcContext.getConnectionManager().isAutoCommit(); +// } +// catch ( SQLException e ) { +// // assume we are in auto-commit! +// return false; +// } + return transaction != null && transaction.isActive(); + } + } Modified: trunk/Hibernate3/src/org/hibernate/transaction/JTATransaction.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/transaction/JTATransaction.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/transaction/JTATransaction.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -332,4 +332,8 @@ throw new TransactionException("could not set transaction timeout", se); } } + + /*package*/ UserTransaction getUserTransaction() { + return ut; + } } Modified: trunk/Hibernate3/src/org/hibernate/transaction/JTATransactionFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/transaction/JTATransactionFactory.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/transaction/JTATransactionFactory.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -5,15 +5,19 @@ import javax.naming.InitialContext; import javax.naming.NamingException; +import javax.transaction.SystemException; +import javax.transaction.UserTransaction; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.ConnectionReleaseMode; import org.hibernate.HibernateException; import org.hibernate.Transaction; +import org.hibernate.TransactionException; import org.hibernate.jdbc.JDBCContext; import org.hibernate.cfg.Environment; import org.hibernate.util.NamingHelper; +import org.hibernate.util.JTAHelper; /** * Factory for <tt>JTATransaction</tt>. @@ -39,7 +43,7 @@ } utName = props.getProperty(Environment.USER_TRANSACTION); - + if (utName==null) { TransactionManagerLookup lookup = TransactionManagerLookupFactory.getTransactionManagerLookup(props); if (lookup!=null) utName = lookup.getUserTransactionName(); @@ -48,7 +52,7 @@ if (utName==null) utName = DEFAULT_USER_TRANSACTION_NAME; } - public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext) + public Transaction createTransaction(JDBCContext jdbcContext, Context transactionContext) throws HibernateException { return new JTATransaction(context, utName, jdbcContext, transactionContext); } @@ -65,4 +69,28 @@ return false; } + public boolean isTransactionInProgress( + JDBCContext jdbcContext, + Context transactionContext, + Transaction transaction) { + try { + UserTransaction ut; + if ( transaction != null ) { + ut = ( ( JTATransaction ) transaction ).getUserTransaction(); + } + else { + try { + ut = ( UserTransaction ) context.lookup( utName ); + } + catch ( NamingException e ) { + throw new TransactionException( "Unable to locate UserTrasnaction to check status" ); + } + } + return ut != null && JTAHelper.isInProgress( ut.getStatus() ); + } + catch( SystemException se ) { + throw new TransactionException( "Unable to check transaction status", se ); + } + } + } Modified: trunk/Hibernate3/src/org/hibernate/transaction/TransactionFactory.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/transaction/TransactionFactory.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/transaction/TransactionFactory.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -61,5 +61,27 @@ */ public boolean isTransactionManagerRequired(); + /** + * Are all transaction callbacks local to Hibernate Transactions? + * Or can the callbacks originate from some other source (e.g. + * a JTA Synchronization). + * + * @return true if callbacks only ever originate from + * the Hibernate {@link Transaction}; false otherwise. + */ public boolean areCallbacksLocalToHibernateTransactions(); + + /** + * Determine whether an underlying transaction is in progress. + * <p/> + * Mainly this is used in determining whether to register a + * synchronization as well as whether or not to circumvent + * auto flushing outside transactions. + * + * @param jdbcContext + * @param transactionContext + * @param transaction + * @return true if an underlying transaction is know to be in effect. + */ + public boolean isTransactionInProgress(JDBCContext jdbcContext, Context transactionContext, Transaction transaction); } Modified: trunk/Hibernate3/src/org/hibernate/util/JTAHelper.java =================================================================== --- trunk/Hibernate3/src/org/hibernate/util/JTAHelper.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/src/org/hibernate/util/JTAHelper.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -17,13 +17,13 @@ public static boolean isRollback(int status) { return status==Status.STATUS_MARKED_ROLLBACK || - status==Status.STATUS_ROLLING_BACK || - status==Status.STATUS_ROLLEDBACK; + status==Status.STATUS_ROLLING_BACK || + status==Status.STATUS_ROLLEDBACK; } public static boolean isInProgress(int status) { return status==Status.STATUS_ACTIVE || - status==Status.STATUS_MARKED_ROLLBACK; + status==Status.STATUS_MARKED_ROLLBACK; } /** @@ -33,7 +33,7 @@ public static boolean isTransactionInProgress(SessionFactoryImplementor factory) { TransactionManager tm = factory.getTransactionManager(); try { - return ( tm!=null && isTransactionInProgress( tm.getTransaction() ) ); + return tm != null && isTransactionInProgress( tm.getTransaction() ); } catch (SystemException se) { throw new TransactionException( "could not obtain JTA Transaction", se ); Modified: trunk/Hibernate3/test/org/hibernate/test/connections/AggressiveReleaseTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/AggressiveReleaseTest.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/AggressiveReleaseTest.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -4,6 +4,7 @@ import org.hibernate.Session; import org.hibernate.ConnectionReleaseMode; import org.hibernate.ScrollableResults; +import org.hibernate.transaction.CMTTransactionFactory; import org.hibernate.impl.SessionImpl; import org.hibernate.util.SerializationHelper; import org.hibernate.test.tm.DummyConnectionProvider; @@ -16,6 +17,9 @@ import junit.framework.TestSuite; import java.sql.Connection; +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; /** * Implementation of AggressiveReleaseTest. @@ -33,9 +37,13 @@ } protected void configure(Configuration cfg) { + super.configure( cfg ); cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString() ); cfg.setProperty( Environment.CONNECTION_PROVIDER, DummyConnectionProvider.class.getName() ); + cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() ); cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName() ); + cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); + cfg.setProperty( Environment.STATEMENT_BATCH_SIZE, "0" ); } protected Session getSessionUnderTest() throws Throwable { @@ -144,4 +152,35 @@ release( s ); done(); } + + public void testConnectionMaintanenceDuringFlush() throws Throwable { + prepare(); + Session s = getSessionUnderTest(); + s.beginTransaction(); + + List entities = new ArrayList(); + for ( int i = 0; i < 10; i++ ) { + Other other = new Other( "other-" + i ); + Silly silly = new Silly( "silly-" + i, other ); + entities.add( silly ); + s.save( silly ); + } + s.flush(); + + Iterator itr = entities.iterator(); + while ( itr.hasNext() ) { + Silly silly = ( Silly ) itr.next(); + silly.setName( "new-" + silly.getName() ); + silly.getOther().setName( "new-" + silly.getOther().getName() ); + } + long initialCount = getSessions().getStatistics().getConnectCount(); + s.flush(); + assertEquals( "connection not maintained through flush", initialCount + 1, getSessions().getStatistics().getConnectCount() ); + + s.createQuery( "delete from Silly" ).executeUpdate(); + s.createQuery( "delete from Other" ).executeUpdate(); + s.getTransaction().commit(); + release( s ); + done(); + } } Modified: trunk/Hibernate3/test/org/hibernate/test/connections/BasicConnectionProviderTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/BasicConnectionProviderTest.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/BasicConnectionProviderTest.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -33,6 +33,7 @@ } protected void configure(Configuration cfg) { + super.configure( cfg ); cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString() ); } } Modified: trunk/Hibernate3/test/org/hibernate/test/connections/ConnectionManagementTestCase.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/ConnectionManagementTestCase.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/ConnectionManagementTestCase.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -4,6 +4,8 @@ import org.hibernate.test.TestCase; import org.hibernate.Session; import org.hibernate.Transaction; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; import org.hibernate.util.SerializationHelper; /** @@ -28,6 +30,9 @@ return new String[] { "connections/Silly.hbm.xml" }; } + protected void configure(Configuration cfg) { + super.configure( cfg ); + } // hooks ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Modified: trunk/Hibernate3/test/org/hibernate/test/connections/CurrentSessionConnectionTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/CurrentSessionConnectionTest.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/CurrentSessionConnectionTest.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -2,10 +2,6 @@ package org.hibernate.test.connections; import org.hibernate.Session; -import org.hibernate.test.tm.DummyConnectionProvider; -import org.hibernate.test.tm.DummyTransactionManagerLookup; -import org.hibernate.cfg.Configuration; -import org.hibernate.cfg.Environment; import junit.framework.Test; import junit.framework.TestSuite; Added: trunk/Hibernate3/test/org/hibernate/test/connections/Other.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/Other.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/Other.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -0,0 +1,32 @@ +package org.hibernate.test.connections; + +/** + * @author Steve Ebersole + */ +public class Other { + private Long id; + private String name; + + public Other() { + } + + public Other(String name) { + this.name = name; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} Modified: trunk/Hibernate3/test/org/hibernate/test/connections/Silly.hbm.xml =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/Silly.hbm.xml 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/Silly.hbm.xml 2006-03-10 18:14:21 UTC (rev 9595) @@ -10,6 +10,14 @@ <generator class="native"/> </id> <property name="name"/> + <many-to-one name="other" class="Other" cascade="all"/> + </class> + + <class name="Other"> + <id name="id" type="long"> + <generator class="native"/> + </id> + <property name="name"/> </class> </hibernate-mapping> \ No newline at end of file Modified: trunk/Hibernate3/test/org/hibernate/test/connections/Silly.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/Silly.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/Silly.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -11,6 +11,7 @@ public class Silly implements Serializable { private Long id; private String name; + private Other other; public Silly() { } @@ -19,6 +20,11 @@ this.name = name; } + public Silly(String name, Other other) { + this.name = name; + this.other = other; + } + public Long getId() { return id; } @@ -34,4 +40,12 @@ public void setName(String name) { this.name = name; } + + public Other getOther() { + return other; + } + + public void setOther(Other other) { + this.other = other; + } } Modified: trunk/Hibernate3/test/org/hibernate/test/connections/SuppliedConnectionTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/SuppliedConnectionTest.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/SuppliedConnectionTest.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -48,6 +48,7 @@ } protected void configure(Configuration cfg) { + super.configure( cfg ); cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.ON_CLOSE.toString() ); cfg.setProperty( Environment.CONNECTION_PROVIDER, UserSuppliedConnectionProvider.class.getName() ); boolean supportsScroll = true; Modified: trunk/Hibernate3/test/org/hibernate/test/connections/ThreadLocalCurrentSessionTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/connections/ThreadLocalCurrentSessionTest.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/connections/ThreadLocalCurrentSessionTest.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -17,6 +17,7 @@ } protected void configure(Configuration cfg) { + super.configure( cfg ); cfg.setProperty( Environment.CURRENT_SESSION_CONTEXT_CLASS, TestableThreadLocalContext.class.getName() ); cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); } Modified: trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/proxy/ProxyTest.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -28,7 +28,7 @@ super(str); } - public void testFInalizeFiltered() { + public void testFinalizeFiltered() { Session s = openSession(); Transaction t = s.beginTransaction(); @@ -199,6 +199,7 @@ dp2 = (DataPoint) s.createQuery("from DataPoint").uniqueResult(); assertSame(dp, dp2); assertTrue( Hibernate.isInitialized(dp) ); + s.delete( dp ); t.commit(); s.close(); } Modified: trunk/Hibernate3/test/org/hibernate/test/tm/CMTTest.java =================================================================== --- trunk/Hibernate3/test/org/hibernate/test/tm/CMTTest.java 2006-03-10 17:09:27 UTC (rev 9594) +++ trunk/Hibernate3/test/org/hibernate/test/tm/CMTTest.java 2006-03-10 18:14:21 UTC (rev 9595) @@ -15,6 +15,7 @@ import org.hibernate.Session; import org.hibernate.ScrollableResults; import org.hibernate.ConnectionReleaseMode; +import org.hibernate.transaction.CMTTransactionFactory; import org.hibernate.util.SerializationHelper; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; @@ -379,7 +380,7 @@ public void testCurrentSessionWithScroll() throws Exception { DummyTransactionManager.INSTANCE.begin(); - Session s = openSession(); + Session s = getSessions().getCurrentSession(); Map item1 = new HashMap(); item1.put( "name", "Item - 1" ); item1.put( "description", "The first item" ); @@ -391,13 +392,21 @@ s.persist( "Item", item2 ); DummyTransactionManager.INSTANCE.getTransaction().commit(); - // First, test partially scrolling the result (w/o closing) + // First, test partially scrolling the result with out closing DummyTransactionManager.INSTANCE.begin(); s = getSessions().getCurrentSession(); ScrollableResults results = s.createQuery( "from Item" ).scroll(); results.next(); DummyTransactionManager.INSTANCE.getTransaction().commit(); + // Next, test partially scrolling the result with closing + DummyTransactionManager.INSTANCE.begin(); + s = getSessions().getCurrentSession(); + results = s.createQuery( "from Item" ).scroll(); + results.next(); + results.close(); + DummyTransactionManager.INSTANCE.getTransaction().commit(); + // Next, scroll the entire result (w/o closing) DummyTransactionManager.INSTANCE.begin(); s = getSessions().getCurrentSession(); @@ -407,6 +416,7 @@ } DummyTransactionManager.INSTANCE.getTransaction().commit(); + // Next, scroll the entire result (closing) DummyTransactionManager.INSTANCE.begin(); s = getSessions().getCurrentSession(); results = s.createQuery( "from Item" ).scroll(); @@ -417,7 +427,7 @@ DummyTransactionManager.INSTANCE.getTransaction().commit(); DummyTransactionManager.INSTANCE.begin(); - s = openSession(); + s = getSessions().getCurrentSession(); s.createQuery( "delete from Item" ).executeUpdate(); DummyTransactionManager.INSTANCE.getTransaction().commit(); } @@ -480,14 +490,15 @@ } protected void configure(Configuration cfg) { - cfg.setProperty(Environment.CONNECTION_PROVIDER, DummyConnectionProvider.class.getName()); - cfg.setProperty(Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName()); - cfg.setProperty(Environment.AUTO_CLOSE_SESSION, "true"); - cfg.setProperty(Environment.FLUSH_BEFORE_COMPLETION, "true"); - cfg.setProperty(Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString()); - cfg.setProperty(Environment.GENERATE_STATISTICS, "true"); - cfg.setProperty(Environment.USE_QUERY_CACHE, "true"); - cfg.setProperty(Environment.DEFAULT_ENTITY_MODE, EntityMode.MAP.toString()); + cfg.setProperty( Environment.CONNECTION_PROVIDER, DummyConnectionProvider.class.getName() ); + cfg.setProperty( Environment.TRANSACTION_MANAGER_STRATEGY, DummyTransactionManagerLookup.class.getName() ); + cfg.setProperty( Environment.TRANSACTION_STRATEGY, CMTTransactionFactory.class.getName() ); + cfg.setProperty( Environment.AUTO_CLOSE_SESSION, "true" ); + cfg.setProperty( Environment.FLUSH_BEFORE_COMPLETION, "true" ); + cfg.setProperty( Environment.RELEASE_CONNECTIONS, ConnectionReleaseMode.AFTER_STATEMENT.toString() ); + cfg.setProperty( Environment.GENERATE_STATISTICS, "true" ); + cfg.setProperty( Environment.USE_QUERY_CACHE, "true" ); + cfg.setProperty( Environment.DEFAULT_ENTITY_MODE, EntityMode.MAP.toString() ); } } |