You are viewing a plain text version of this content. The canonical link for it is here.
Posted to torque-dev@db.apache.org by tf...@apache.org on 2012/10/15 03:49:32 UTC

svn commit: r1398168 - in /db/torque/torque4/trunk: torque-runtime/src/main/java/org/apache/torque/ torque-runtime/src/main/java/org/apache/torque/util/ torque-test/src/test/java/org/apache/torque/util/ torque-test/src/test/profile/derbyEmbedded/ torqu...

Author: tfischer
Date: Mon Oct 15 01:49:31 2012
New Revision: 1398168

URL: http://svn.apache.org/viewvc?rev=1398168&view=rev
Log:
TORQUE-233 Add exception translation

Added:
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/ConstraintViolationException.java   (with props)
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/DeadlockException.java   (with props)
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapper.java   (with props)
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapperImpl.java   (with props)
    db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/util/ExceptionMapperTest.java
Modified:
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java
    db/torque/torque4/trunk/torque-test/src/test/profile/derbyEmbedded/Torque.properties
    db/torque/torque4/trunk/torque-test/src/test/profile/hsqldb/Torque.properties
    db/torque/torque4/trunk/torque-test/src/test/profile/postgresql/Torque.properties

Added: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/ConstraintViolationException.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/ConstraintViolationException.java?rev=1398168&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/ConstraintViolationException.java (added)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/ConstraintViolationException.java Mon Oct 15 01:49:31 2012
@@ -0,0 +1,63 @@
+package org.apache.torque;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This exception is thrown if a database operation violates a
+ * database constraint, e.g. a foreign key constraint, a unique constraint or a
+ * not-null constraint.
+ *
+ * @version $Id$
+ */
+public class ConstraintViolationException extends TorqueException
+{
+    /**
+     * Serial version.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructs a new <code>ConstraintViolationException</code>
+     * with specified nested <code>Throwable</code>.
+     *
+     * @param nested the exception or error that caused this exception
+     *               to be thrown.
+     */
+    public ConstraintViolationException(Throwable nested)
+    {
+        super(nested);
+    }
+
+    /**
+     * Constructs a new <code>ConstraintViolationException</code>
+     * with specified detail message and nested <code>Throwable</code>.
+     *
+     * @param msg the error message.
+     * @param nested the exception or error that caused this exception
+     *               to be thrown.
+     */
+    public ConstraintViolationException(
+            String msg,
+            Throwable nested)
+    {
+        super(msg, nested);
+    }
+
+}

Propchange: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/ConstraintViolationException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/DeadlockException.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/DeadlockException.java?rev=1398168&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/DeadlockException.java (added)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/DeadlockException.java Mon Oct 15 01:49:31 2012
@@ -0,0 +1,60 @@
+package org.apache.torque;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/**
+ * This exception is thrown if the database detects a deadlock.
+ *
+ * @version $Id$
+ */
+public class DeadlockException extends TorqueException
+{
+    /**
+     * Serial version.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructs a new <code>DeadlockException</code>
+     * with specified nested <code>Throwable</code>.
+     *
+     * @param nested the exception or error that caused this exception
+     *               to be thrown.
+     */
+    public DeadlockException(Throwable nested)
+    {
+        super(nested);
+    }
+
+    /**
+     * Constructs a new <code>DeadlockException</code>
+     * with specified detail message and nested <code>Throwable</code>.
+     *
+     * @param msg the error message.
+     * @param nested the exception or error that caused this exception
+     *               to be thrown.
+     */
+    public DeadlockException(
+            String msg,
+            Throwable nested)
+    {
+        super(msg, nested);
+    }
+}

Propchange: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/DeadlockException.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Modified: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java?rev=1398168&r1=1398167&r2=1398168&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java (original)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/BasePeerImpl.java Mon Oct 15 01:49:31 2012
@@ -191,17 +191,18 @@ public class BasePeerImpl<T> implements 
     }
 
     /**
-     * Get the list of objects for a ResultSet.  Please not that your
-     * resultset MUST return columns in the right order.  You can use
-     * getFieldNames() in BaseObject to get the correct sequence.
+     * Get the list of objects from a ResultSet.
+     * Please not that the ResultSet MUST return columns in the right order.
+     * You can use getFieldNames() in BaseObject to get the correct sequence.
      *
-     * @param resultSet the ResultSet
-     * @return the list of objects
-     * @throws TorqueException Any exceptions caught during processing will be
-     *         rethrown wrapped into a TorqueException.
+     * @param resultSet the ResultSet to extract the objects from.
+     *
+     * @return the list of objects read from the ResultSet.
+     *
+     * @throws TorqueException If the mapping fails.
      */
     public List<T> resultSet2Objects(java.sql.ResultSet resultSet)
-            throws TorqueException
+        throws TorqueException
     {
         try
         {
@@ -215,7 +216,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
     }
 
@@ -355,7 +356,8 @@ public class BasePeerImpl<T> implements 
      * @throws TorqueException Any exceptions caught during processing will be
      *         rethrown wrapped into a TorqueException.
      */
-     public int doDelete(org.apache.torque.criteria.Criteria criteria) throws TorqueException
+     public int doDelete(org.apache.torque.criteria.Criteria criteria)
+             throws TorqueException
      {
         Connection connection = null;
         try
@@ -451,7 +453,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
         finally
         {
@@ -599,7 +601,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
         finally
         {
@@ -808,7 +810,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
         finally
         {
@@ -1241,7 +1243,7 @@ public class BasePeerImpl<T> implements 
      * @param mapper The mapper creating the objects from the resultSet,
      *        not null.
      * @param dbName The name of the database to create the connection for,
-     *        or null for the default SDB.
+     *        or null for the default DB.
      *
      * @return The results of the query, not null.
      *
@@ -1327,7 +1329,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
         finally
         {
@@ -1481,7 +1483,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
         finally
         {
@@ -1633,7 +1635,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
         finally
         {
@@ -1993,7 +1995,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
         finally
         {
@@ -2090,7 +2092,7 @@ public class BasePeerImpl<T> implements 
         }
         catch (SQLException e)
         {
-            throw new TorqueException(e);
+            throw ExceptionMapper.getInstance().toTorqueException(e);
         }
         finally
         {
@@ -2129,8 +2131,11 @@ public class BasePeerImpl<T> implements 
      * statements.  Use executeQuery() for selects.
      *
      * @param statementString A String with the sql statement to execute.
-     * @param dbName Name of database to connect to.
+     * @param dbName The name of the database to execute the statement against,
+     *        or null for the default DB.
+     *
      * @return The number of rows affected.
+     *
      * @throws TorqueException Any exceptions caught during processing will be
      *         rethrown wrapped into a TorqueException.
      */
@@ -2161,12 +2166,16 @@ public class BasePeerImpl<T> implements 
      * statements.  Use executeQuery() for selects.
      *
      * @param statementString A String with the sql statement to execute.
-     * @param con A Connection.
+     * @param con The database connection to use.
+     *
      * @return The number of rows affected.
+     *
      * @throws TorqueException Any exceptions caught during processing will be
      *         rethrown wrapped into a TorqueException.
      */
-    public int executeStatement(String statementString, Connection con)
+    public int executeStatement(
+            String statementString,
+            Connection con)
         throws TorqueException
     {
         int rowCount = -1;
@@ -2555,7 +2564,8 @@ public class BasePeerImpl<T> implements 
      *
      * @param crit the criteria to set the database name in, not null.
      */
-    protected void setDbName(org.apache.torque.criteria.Criteria crit) throws TorqueException
+    protected void setDbName(org.apache.torque.criteria.Criteria crit)
+            throws TorqueException
     {
         if (crit.getDbName() == null)
         {

Added: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapper.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapper.java?rev=1398168&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapper.java (added)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapper.java Mon Oct 15 01:49:31 2012
@@ -0,0 +1,64 @@
+package org.apache.torque.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.sql.SQLException;
+
+import org.apache.torque.TorqueException;
+
+/**
+ * Translates Database Exceptions into TorqueExceptions.
+ * @version $Id$
+ */
+public abstract class ExceptionMapper
+{
+    /** The Exception mapper instance. */
+    private static ExceptionMapper instance = new ExceptionMapperImpl();
+
+    /**
+     * Returns the current instance of the Exception mapper to use.
+     *
+     * @return the current Exception mapper instance.
+     */
+    public static final ExceptionMapper getInstance()
+    {
+        return instance;
+    }
+
+    /**
+     * Sets a new instance of an Exception mapper to use.
+     *
+     * @param newInstance the new Exception mapper instance, not null.
+     */
+    public static final void setInstance(ExceptionMapper newInstance)
+    {
+        instance = newInstance;
+    }
+
+    /**
+     * Maps a SQLException to an appropriate TorqueException.
+     *
+     * @param sqlException the sqlException to map, not null.
+     *
+     * @return the maped TorqueException, containing the original
+     *         exception as a cause, not null.
+     */
+    public abstract TorqueException toTorqueException(SQLException sqlException);
+}

Propchange: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapper.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapperImpl.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapperImpl.java?rev=1398168&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapperImpl.java (added)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapperImpl.java Mon Oct 15 01:49:31 2012
@@ -0,0 +1,55 @@
+package org.apache.torque.util;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.sql.SQLException;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.torque.ConstraintViolationException;
+import org.apache.torque.DeadlockException;
+import org.apache.torque.TorqueException;
+
+/**
+ * Default implementation of the ExceptionMapper interface.
+ * @version $Id$
+ */
+public class ExceptionMapperImpl extends ExceptionMapper
+{
+
+    @Override
+    public TorqueException toTorqueException(SQLException sqlException)
+    {
+        if (StringUtils.startsWith(sqlException.getSQLState(), "23"))
+        {
+            return new ConstraintViolationException(sqlException);
+        }
+        if (StringUtils.equals(sqlException.getSQLState(), "40001"))
+        {
+            // mysql, derby
+            return new DeadlockException(sqlException);
+        }
+        if (StringUtils.equals(sqlException.getSQLState(), "40P01"))
+        {
+            // postgresql
+            return new DeadlockException(sqlException);
+        }
+        return new TorqueException(sqlException);
+    }
+}

Propchange: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/util/ExceptionMapperImpl.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/util/ExceptionMapperTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/util/ExceptionMapperTest.java?rev=1398168&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/util/ExceptionMapperTest.java (added)
+++ db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/util/ExceptionMapperTest.java Mon Oct 15 01:49:31 2012
@@ -0,0 +1,274 @@
+package org.apache.torque.util;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.torque.BaseDatabaseTestCase;
+import org.apache.torque.ConstraintViolationException;
+import org.apache.torque.DeadlockException;
+import org.apache.torque.Torque;
+import org.apache.torque.TorqueException;
+import org.apache.torque.adapter.Adapter;
+import org.apache.torque.adapter.HsqldbAdapter;
+import org.apache.torque.criteria.Criteria;
+import org.apache.torque.test.dbobject.Author;
+import org.apache.torque.test.dbobject.Book;
+import org.apache.torque.test.dbobject.SingleNamedUnique;
+import org.apache.torque.test.peer.AuthorPeer;
+import org.apache.torque.test.peer.SingleNamedUniquePeer;
+
+public class ExceptionMapperTest extends BaseDatabaseTestCase
+{
+    /** Sleep time for thread polling, in miliseconds. */
+    private static int SLEEP_TIME = 10;
+
+    /** Timeout for waiting for started threads and saves, in miliseconds. */
+    private static int TIMEOUT = 1000;
+
+    private static Log log = LogFactory.getLog(ExceptionMapperTest.class);
+
+    /**
+     * Check that a ConstraintViolationException is thrown if a record
+     * with an already-existing primary key is inserted.
+     */
+    public void testInsertWithPkViolation() throws TorqueException
+    {
+        // prepare
+        cleanBookstore();
+        List<Author> bookstoreContent = insertBookstoreData();
+        Author author = new Author();
+        author.setName("Author");
+        author.setAuthorId(bookstoreContent.get(0).getAuthorId());
+
+        // execute & verify
+        try
+        {
+            author.save();
+            fail("Exception expected");
+        }
+        catch (ConstraintViolationException e)
+        {
+            assertTrue(e.getCause() instanceof SQLException);
+        }
+    }
+
+    /**
+     * Check that a ConstraintViolationException is thrown if a record
+     * with an already-existing unique key is inserted.
+     */
+    public void testUpdateWithUniqueConstraintViolation() throws TorqueException
+    {
+        // prepare
+        SingleNamedUniquePeer.doDelete(new Criteria());
+        SingleNamedUnique unique = new SingleNamedUnique();
+        unique.setValue(1);
+        unique.save();
+
+        SingleNamedUnique duplicateUnique = new SingleNamedUnique();
+        duplicateUnique.setValue(1);
+
+        // execute & verify
+        try
+        {
+            duplicateUnique.save();
+            fail("Exception expected");
+        }
+        catch (ConstraintViolationException e)
+        {
+            assertTrue(e.getCause() instanceof SQLException);
+        }
+    }
+
+    /**
+     * Check that a ConstraintViolationException is thrown if a record
+     * is saved which contains null in a non-nullable column
+     */
+    public void testInsertWithNonNullableColumnViolation()
+            throws TorqueException
+    {
+        // prepare
+        cleanBookstore();
+        Author author = new Author();
+        author.setName(null); // is required
+
+        // execute & verify
+        try
+        {
+            author.save();
+            fail("Exception expected");
+        }
+        catch (ConstraintViolationException e)
+        {
+            assertTrue(e.getCause() instanceof SQLException);
+        }
+    }
+
+    /**
+     * Check that a ConstraintViolationException is thrown if a record
+     * is saved which has a foreign key to a non-existing object
+     */
+    public void testInsertWithForeignKeyConstraintViolation()
+            throws TorqueException
+    {
+        // prepare
+        cleanBookstore();
+        Book book = new Book();
+        book.setTitle("title");
+        book.setIsbn("isbn");
+        book.setAuthorId(1); // does not exist
+
+        // execute & verify
+        try
+        {
+            book.save();
+            fail("Exception expected");
+        }
+        catch (ConstraintViolationException e)
+        {
+            assertTrue(e.getCause() instanceof SQLException);
+        }
+    }
+
+    /**
+     * Check that a deadlockExcetion is thrown if two transaction want to access
+     * a resource locked by the other thread.
+     *
+     * @throws Exception if an error occurs.
+     */
+    public void testTransactionDeadlock() throws Exception
+    {
+        Adapter adapter
+            = Torque.getDatabase(Torque.getDefaultDB()).getAdapter();
+        if (adapter instanceof HsqldbAdapter)
+        {
+            log.warn("hsqldb (2.2.6) fails to detect the deadlock in this test"
+                    + " therefore this test is skipped");
+            return;
+        }
+
+        // prepare
+        cleanBookstore();
+        List<Author> bookstoreContent = insertBookstoreData();
+        Connection transaction1 = null;
+        Connection transaction2 = null;
+        try
+        {
+            // lock author 1 in transaction 1
+            transaction1 = Transaction.begin();
+            if (transaction1.getAutoCommit())
+            {
+                fail("autocommit must be set to false for this test");
+            }
+            Author author1 = bookstoreContent.get(0);
+            author1.setName("new Author1");
+            author1.save(transaction1);
+
+            // lock author 2 in transaction 2
+            transaction2 = Transaction.begin();
+            if (transaction2.getAutoCommit())
+            {
+                fail("autocommit must be set to false for this test(2)");
+            }
+            Author author2 = bookstoreContent.get(1);
+            author2.setName("new Author2");
+            author2.save(transaction2);
+
+            // lock author 2 in transaction 1 (must wait for lock)
+            author2.setName("newer Author2");
+            SaveThread saveThreadTransaction1
+                = new SaveThread(author2, transaction1);
+            saveThreadTransaction1.start();
+
+            long startTime = System.currentTimeMillis();
+            while (!author2.isSaving() && author2.isModified())
+            {
+                Thread.sleep(SLEEP_TIME);
+                if (System.currentTimeMillis() > startTime + TIMEOUT)
+                {
+                    fail("Waited too long for saving to start");
+                }
+            }
+
+            // Try to lock author1 in transaction 2 (deadlock)
+            author1.setName("newer Author1");
+            DeadlockException deadlockExceptionTransaction2 = null;
+            try
+            {
+                author1.save(transaction2);
+            }
+            catch (DeadlockException e)
+            {
+                deadlockExceptionTransaction2 = e;
+            }
+
+            // wait till save on transaction 1 has finished
+            startTime = System.currentTimeMillis();
+            while (saveThreadTransaction1.isAlive())
+            {
+                Thread.sleep(10);
+                if (System.currentTimeMillis() > startTime + TIMEOUT)
+                {
+                    fail("Waited too long for saving to finish");
+                }
+            }
+
+            // verify. Either in transaction 1 or in transaction 2
+            // a deadlock exception must have occurred
+            if (deadlockExceptionTransaction2 != null)
+            {
+                return;
+            }
+            if (saveThreadTransaction1.getCaughtException() == null)
+            {
+                fail("No Deadlock occured");
+            }
+            if (!(saveThreadTransaction1.getCaughtException()
+                    instanceof DeadlockException))
+            {
+                throw saveThreadTransaction1.getCaughtException();
+            }
+        }
+        finally
+        {
+            Transaction.safeRollback(transaction1);
+            Transaction.safeRollback(transaction2);
+        }
+    }
+
+    private static class SaveThread extends Thread
+    {
+        private final Author toSave;
+
+        private final Connection transaction;
+
+        private TorqueException caughtException;
+
+        public SaveThread(Author toSave, Connection transaction)
+        {
+            this.toSave = toSave;
+            this.transaction = transaction;
+        }
+
+        @Override
+        public void run()
+        {
+            try
+            {
+                toSave.save(transaction);
+            }
+            catch (TorqueException e)
+            {
+                caughtException = e;
+            }
+        }
+
+        public TorqueException getCaughtException()
+        {
+            return caughtException;
+        }
+    }
+
+}

Modified: db/torque/torque4/trunk/torque-test/src/test/profile/derbyEmbedded/Torque.properties
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/profile/derbyEmbedded/Torque.properties?rev=1398168&r1=1398167&r2=1398168&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/profile/derbyEmbedded/Torque.properties (original)
+++ db/torque/torque4/trunk/torque-test/src/test/profile/derbyEmbedded/Torque.properties Mon Oct 15 01:49:31 2012
@@ -21,16 +21,14 @@
 torque.database.default = bookstore
 torque.database.bookstore.adapter = derby
 
-#Using commons-dbcp
 torque.dsfactory.bookstore.factory = org.apache.torque.dsfactory.SharedPoolDataSourceFactory
-
 torque.dsfactory.bookstore.connection.driver = org.apache.derby.jdbc.EmbeddedDriver
 torque.dsfactory.bookstore.connection.url = jdbc:derby:target/bookstore;create=true
-
 torque.dsfactory.bookstore.connection.user = 
 torque.dsfactory.bookstore.connection.password = 
 
 torque.dsfactory.bookstore.pool.validationQuery = values(1)
+torque.dsfactory.bookstore.pool.defaultAutoCommit = false
 
 # use Caching. This property is only used if managers are used by generators.
 torque.manager.useCache = true

Modified: db/torque/torque4/trunk/torque-test/src/test/profile/hsqldb/Torque.properties
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/profile/hsqldb/Torque.properties?rev=1398168&r1=1398167&r2=1398168&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/profile/hsqldb/Torque.properties (original)
+++ db/torque/torque4/trunk/torque-test/src/test/profile/hsqldb/Torque.properties Mon Oct 15 01:49:31 2012
@@ -24,7 +24,6 @@
 torque.database.default = bookstore
 torque.database.bookstore.adapter = hsqldb
 
-# Using commons-dbcp
 torque.dsfactory.bookstore.factory = org.apache.torque.dsfactory.SharedPoolDataSourceFactory
 torque.dsfactory.bookstore.connection.driver = org.hsqldb.jdbcDriver
 torque.dsfactory.bookstore.connection.url =jdbc:hsqldb:target/sqltest
@@ -32,6 +31,7 @@ torque.dsfactory.bookstore.connection.us
 torque.dsfactory.bookstore.connection.password = 
 
 torque.dsfactory.bookstore.pool.validationQuery = CALL NOW
+torque.dsfactory.bookstore.pool.defaultAutoCommit = false
 
 # use Caching. This property is only used if managers are used by generators.
 torque.manager.useCache = true

Modified: db/torque/torque4/trunk/torque-test/src/test/profile/postgresql/Torque.properties
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/profile/postgresql/Torque.properties?rev=1398168&r1=1398167&r2=1398168&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/profile/postgresql/Torque.properties (original)
+++ db/torque/torque4/trunk/torque-test/src/test/profile/postgresql/Torque.properties Mon Oct 15 01:49:31 2012
@@ -24,7 +24,6 @@
 torque.database.default = bookstore
 torque.database.bookstore.adapter = postgresql
 
-# Using commons-dbcp
 torque.dsfactory.bookstore.factory = org.apache.torque.dsfactory.SharedPoolDataSourceFactory
 torque.dsfactory.bookstore.connection.driver = org.postgresql.Driver
 torque.dsfactory.bookstore.connection.url = jdbc:postgresql://localhost:5432/bookstore
@@ -32,6 +31,7 @@ torque.dsfactory.bookstore.connection.us
 torque.dsfactory.bookstore.connection.password = torque
 
 torque.dsfactory.bookstore.pool.validationQuery = SELECT 1
+torque.dsfactory.bookstore.pool.defaultAutoCommit = false
 
 # use Caching. This property is only used if managers are used by generators.
 torque.manager.useCache = true
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: torque-dev-unsubscribe@db.apache.org
For additional commands, e-mail: torque-dev-help@db.apache.org