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 2013/02/19 09:49:59 UTC

svn commit: r1447627 - in /db/torque/torque4/trunk: torque-runtime/src/main/java/org/apache/torque/ torque-templates/src/main/java/org/apache/torque/templates/ torque-templates/src/main/java/org/apache/torque/templates/transformer/om/ torque-templates/...

Author: tfischer
Date: Tue Feb 19 08:49:59 2013
New Revision: 1447627

URL: http://svn.apache.org/r1447627
Log:
TORQUE-267 Add optimistic locking 

Added:
    db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/OptimisticLockingFailedException.java   (with props)
    db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingInterface.java
    db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingPeerInterface.java
    db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/BaseOptimisticLockingTest.java   (with props)
    db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSelectForUpdateTest.java   (with props)
    db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSimpleSelectTest.java   (with props)
Modified:
    db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TemplateOptionName.java
    db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TorqueSchemaAttributeName.java
    db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/ColumnAttributeName.java
    db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/OMColumnTransformer.java
    db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/conf/options.properties
    db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/doUpdate.vm
    db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/imports.vm
    db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/peerImpl.vm
    db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/transformer/om/OMTableTransformer.properties
    db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/xsd/database-4-0.xsd
    db/torque/torque4/trunk/torque-test/src/main/schema/test-schema.xml

Added: db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/OptimisticLockingFailedException.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/OptimisticLockingFailedException.java?rev=1447627&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/OptimisticLockingFailedException.java (added)
+++ db/torque/torque4/trunk/torque-runtime/src/main/java/org/apache/torque/OptimisticLockingFailedException.java Tue Feb 19 08:49:59 2013
@@ -0,0 +1,73 @@
+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 that a row in a table
+ * with optimistic locking was updated by another process.
+ *
+ * @version $Id$
+ */
+public class OptimisticLockingFailedException extends TorqueException
+{
+    /**
+     * Serial version.
+     */
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Constructs a new <code>ConcurrentUpdateException</code>
+     * with specified nested <code>Throwable</code>.
+     *
+     * @param nested the exception or error that caused this exception
+     *               to be thrown.
+     */
+    public OptimisticLockingFailedException(Throwable nested)
+    {
+        super(nested);
+    }
+
+    /**
+     * Constructs a new <code>ConcurrentUpdateException</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 OptimisticLockingFailedException(
+            String msg,
+            Throwable nested)
+    {
+        super(msg, nested);
+    }
+
+    /**
+     * Constructs a new <code>ConcurrentUpdateException</code>
+     * with specified detail message.
+     *
+     * @param msg the error message.
+     */
+    public OptimisticLockingFailedException(
+            String msg)
+    {
+        super(msg);
+    }
+}

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

Modified: db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TemplateOptionName.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TemplateOptionName.java?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TemplateOptionName.java (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TemplateOptionName.java Tue Feb 19 08:49:59 2013
@@ -207,7 +207,19 @@ public enum TemplateOptionName implement
      * The name of the option for the name of the exception thrown
      * by the save methods.
      */
-    OM_SAVE_EXCEPTION("torque.om.saveException");
+    OM_SAVE_EXCEPTION("torque.om.saveException"),
+
+    /**
+     * The name of the option for the default value used in optimistic locking
+     * if no explicit default value is set.
+     */
+    OM_OPTIMISTIC_LOCKING_DEFAULT_VALUE("torque.om.optimisticLocking.defaultValue"),
+
+    /**
+     * The name of the option for the mode used in optimistic locking.
+     * The value must be one of selectForUpdate, simpleSelect.
+     */
+    OM_OPTIMISTIC_LOCKING_MODE("torque.om.optimisticLocking.mode");
 
     /**
      * The fully qualified name of the option.

Modified: db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TorqueSchemaAttributeName.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TorqueSchemaAttributeName.java?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TorqueSchemaAttributeName.java (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/TorqueSchemaAttributeName.java Tue Feb 19 08:49:59 2013
@@ -87,7 +87,9 @@ public enum TorqueSchemaAttributeName im
     /** attribute key */
     KEY("key"),
     /** attribute skipSql */
-    SKIP_SQL("skipSql");
+    SKIP_SQL("skipSql"),
+    /** attribute version */
+    VERSION ("version");
 
     /** The name of the attribute, not null. */
     private String name;

Modified: db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/ColumnAttributeName.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/ColumnAttributeName.java?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/ColumnAttributeName.java (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/ColumnAttributeName.java Tue Feb 19 08:49:59 2013
@@ -54,9 +54,9 @@ public enum ColumnAttributeName implemen
     POSITION("position"),
 
     /**
-     * The village method to retrieve a value for this column.
+     * The object (non-primitive) type for a field.
      */
-    VILLAGE_METHOD("villageMethod"),
+    FIELD_OBJECT_TYPE("fieldObjectType"),
 
     /**
      * The getter to get the column from a result set.

Modified: db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/OMColumnTransformer.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/OMColumnTransformer.java?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/OMColumnTransformer.java (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/java/org/apache/torque/templates/transformer/om/OMColumnTransformer.java Tue Feb 19 08:49:59 2013
@@ -33,6 +33,7 @@ import org.apache.torque.generator.proce
 import org.apache.torque.generator.processor.string.WrapReservedJavaWords;
 import org.apache.torque.generator.source.SourceElement;
 import org.apache.torque.generator.source.transform.SourceTransformerException;
+import org.apache.torque.templates.TemplateOptionName;
 import org.apache.torque.templates.TorqueSchemaAttributeName;
 import org.apache.torque.templates.TorqueSchemaElementName;
 import org.apache.torque.templates.TorqueSchemaInheritance;
@@ -122,6 +123,10 @@ public class OMColumnTransformer
         columnElement.setAttribute(
                 JavaFieldAttributeName.FIELD_TYPE,
                 fieldJavaType.getFullClassName());
+        JavaType fieldJavaObjectType = TypeMap.getJavaObjectType(schemaType);
+        columnElement.setAttribute(
+                ColumnAttributeName.FIELD_OBJECT_TYPE,
+                fieldJavaObjectType.getFullClassName());
 
 
         setPrimitiveTypeAttribute(columnElement, fieldJavaType);
@@ -133,7 +138,7 @@ public class OMColumnTransformer
         setGetterNameAttribute(columnElement, fieldJavaType, controllerState);
         setSetterNameAttribute(columnElement);
         setAccessModifierAttributes(columnElement);
-        setDefaultValueAttribute(columnElement, fieldJavaType);
+        setDefaultValueAttribute(columnElement, fieldJavaType, controllerState);
         setUseDatabaseDefaultValueAttribute(columnElement);
         setResultSetGetterAttribute(columnElement, schemaType);
         setSampleObjectAttribute(columnElement, schemaType);
@@ -595,13 +600,15 @@ public class OMColumnTransformer
      * @param columnElement the column element, not null.
      * @param javaType the type of the java field corresponding to the
      *        column, not null.
+     * @param controllerState the ControllerState, not null.
      *
      * @throws SourceTransformerException if an unknown primitive type
      *         is encountered
      */
     protected void setDefaultValueAttribute(
                 SourceElement columnElement,
-                JavaType javaType)
+                JavaType javaType,
+                ControllerState controllerState)
             throws SourceTransformerException
     {
         // special case inheritance by class name
@@ -639,6 +646,12 @@ public class OMColumnTransformer
                     useDatabaseDefaultValue,
                     columnElement);
         }
+        else if ("true".equals(
+                columnElement.getAttribute(TorqueSchemaAttributeName.VERSION)))
+        {
+            fieldDefaultValue = controllerState.getStringOption(
+                    TemplateOptionName.OM_OPTIMISTIC_LOCKING_DEFAULT_VALUE);
+        }
         else
         {
             fieldDefaultValue = getDefaultValueWithoutDefaultSet(javaType);

Modified: db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/conf/options.properties
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/conf/options.properties?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/conf/options.properties (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/conf/options.properties Tue Feb 19 08:49:59 2013
@@ -193,6 +193,13 @@ torque.om.complexObjectModel.setAndSaveS
 # The default chunk size for the filler methods.
 torque.om.complexObjectModel.defaultFillerChunkSize=999
 
+# The name of the option for the default value used in optimistic locking
+# if no explicit default value is set.
+torque.om.optimisticLocking.defaultValue = 0
+# The name of the option for the default mode used in optimistic locking.
+# Must be one of selectForUpdate, simpleSelect.
+torque.om.optimisticLocking.mode = selectForUpdate
+
 # The default base class for all data objects.
 # can be overridden by setting the baseClass attribute on a table.
 torque.om.dbObjectDefaultBaseClass = 

Modified: db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/doUpdate.vm
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/doUpdate.vm?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/doUpdate.vm (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/doUpdate.vm Tue Feb 19 08:49:59 2013
@@ -80,16 +80,72 @@
         correctBooleans(columnValues);
 
 #foreach ($columnElement in $torqueGen.getChildren("column"))
-
   #if($columnElement.getAttribute("primaryKey") == "true")
     #set ( $peerColumnName = $columnElement.getAttribute("peerColumnName") )
-    
         selectCriteria.where(
                 ${peerClassName}.${peerColumnName},
                 columnValues.remove(${peerClassName}.${peerColumnName}).getValue());
   #end
 #end
-        return doUpdate(selectCriteria, columnValues, con);
+
+#foreach ($columnElement in $torqueGen.getChildren("column"))
+  #if($columnElement.getAttribute("version") == "true")
+    #set ( $containsVersion = true )
+    #set ( $peerColumnName = $columnElement.getAttribute("peerColumnName") )
+    #set ( $columnFieldObjectType = $columnElement.getAttribute("fieldObjectType"))
+    #set ( $columnField = $columnElement.getAttribute("field"))
+        $columnFieldObjectType $columnField = ($columnFieldObjectType) columnValues.get(
+                ${peerClassName}.${peerColumnName}).getValue();
+  #end
+#end
+#if ($containsVersion && $optimisticLockingMode == "selectForUpdate")
+        Criteria lockCriteria = new Criteria(selectCriteria);
+        lockCriteria.forUpdate();
+        $dbObjectClassName $field 
+                = doSelectSingleRecord(lockCriteria, con);
+  #foreach ($columnElement in $torqueGen.getChildren("column"))
+    #if($columnElement.getAttribute("version") == "true")
+      #set ( $columnGetter = $columnElement.getAttribute("getter"))
+        if ($field == null) 
+        {
+            throw new OptimisticLockingFailedException(
+               "The row was deleted concurrently");
+        }
+        if (!ObjectUtils.equals(
+                ${field}.${columnGetter}(),
+                $columnField))
+        {
+            throw new OptimisticLockingFailedException(
+               "The row was updated concurrently");
+        }
+    #end
+  #end
+#end
+#foreach ($columnElement in $torqueGen.getChildren("column"))
+  #if($columnElement.getAttribute("version") == "true")
+    #set ( $peerColumnName = $columnElement.getAttribute("peerColumnName") )
+    #set ( $columnFieldObjectType = $columnElement.getAttribute("fieldObjectType"))
+    #set ( $columnField = $columnElement.getAttribute("field"))
+    #if ( $optimisticLockingMode == "simpleSelect" )
+        selectCriteria.where(
+                ${peerClassName}.${peerColumnName},
+                $columnField);
+    #end
+        columnValues.get(${peerClassName}.${peerColumnName})
+                .setValue($columnField + 1);
+  #end
+#end
+
+        int rowCount = doUpdate(selectCriteria, columnValues, con);
+#if ($containsVersion && $optimisticLockingMode == "simpleSelect")
+        if (rowCount == 0) 
+        {
+            throw new OptimisticLockingFailedException(
+               "The row was either updated or deleted concurrently "
+               + "or does not exist at all.");
+        }
+#end
+        return rowCount;
     }
 
     /**
@@ -111,6 +167,13 @@
 #else
         ColumnValues columnValues = buildColumnValues(obj);
         int result = doUpdate(columnValues);
+#foreach ($columnElement in $torqueGen.getChildren("column"))
+  #if($columnElement.getAttribute("version") == "true")
+    #set ( $columnGetter = $columnElement.getAttribute("getter"))
+    #set ( $columnSetter = $columnElement.getAttribute("setter"))
+        obj.${columnSetter}(obj.${columnGetter}() + 1);
+  #end
+#end
         obj.setModified(false);
         return result;
 #end
@@ -139,6 +202,13 @@
   #else
         ColumnValues columnValues = buildColumnValues(obj);
         int result = doUpdate(columnValues, con);
+#foreach ($columnElement in $torqueGen.getChildren("column"))
+  #if($columnElement.getAttribute("version") == "true")
+    #set ( $columnGetter = $columnElement.getAttribute("getter"))
+    #set ( $columnSetter = $columnElement.getAttribute("setter"))
+        obj.${columnSetter}(obj.${columnGetter}() + 1);
+  #end
+#end
         obj.setModified(false);
         return result;
   #end

Modified: db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/imports.vm
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/imports.vm?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/imports.vm (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/base/imports.vm Tue Feb 19 08:49:59 2013
@@ -52,9 +52,11 @@ import java.util.HashMap;
 import java.util.Set;
 import java.util.HashSet;
 
+import org.apache.commons.lang.ObjectUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.torque.NoRowsException;
+import org.apache.torque.OptimisticLockingFailedException;
 import org.apache.torque.TooManyRowsException;
 import org.apache.torque.Torque;
 import org.apache.torque.TorqueException;

Modified: db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/peerImpl.vm
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/peerImpl.vm?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/peerImpl.vm (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/om/templates/peer/impl/peerImpl.vm Tue Feb 19 08:49:59 2013
@@ -28,6 +28,9 @@ package ${peerPackage};
 $torqueGen.mergepoint("classJavadoc")
 public class ${peerImplClassName}
     extends ${basePeerPackage}.${basePeerImplClassName}
+#if ($peerInterface)
+    implements $peerInterface
+#end
 {
 $torqueGen.mergepoint("serialVersionUid")
 $torqueGen.mergepoint("extensions")

Modified: db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/transformer/om/OMTableTransformer.properties
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/transformer/om/OMTableTransformer.properties?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/transformer/om/OMTableTransformer.properties (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/transformer/om/OMTableTransformer.properties Tue Feb 19 08:49:59 2013
@@ -38,3 +38,5 @@ ${attribute(noOverride):baseManagerPacka
 ${attribute(noOverride):beanPackage}=${option:torque.om.package.package}${option:torque.om.package.beanPackageSuffix}
 ${attribute(noOverride):baseBeanPackage}=${option:torque.om.package.package}${option:torque.om.package.baseBeanPackageSuffix}
 ${attribute(noOverride):mapBuilderPackage}=${option:torque.om.package.package}${option:torque.om.package.mapPackageSuffix}
+
+${attribute(noOverride):optimisticLockingMode}=${option:torque.om.optimisticLocking.mode}

Modified: db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/xsd/database-4-0.xsd
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/xsd/database-4-0.xsd?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/xsd/database-4-0.xsd (original)
+++ db/torque/torque4/trunk/torque-templates/src/main/resources/org/apache/torque/templates/xsd/database-4-0.xsd Tue Feb 19 08:49:59 2013
@@ -523,6 +523,19 @@ than public.
         </xs:documentation>
       </xs:annotation>
     </xs:attribute>
+    <xs:attribute name="version" use="optional"
+                  type="xs:boolean" default="false" >
+      <xs:annotation>
+        <xs:documentation xml:lang="en">
+If true, this column is used as a version number for optimistic locking.
+I.e. for updates, Torque will check that the version number in the database
+is equal to the version number of the supplied object
+and it will automatically increase the version number of the updated row.
+Setting version to true will only work for numeric columns and will produce
+code that does not compile if applied to other column types.
+        </xs:documentation>
+      </xs:annotation>
+    </xs:attribute>
     <xs:attribute name="description" type="xs:string" use="optional" >
       <xs:annotation>
         <xs:documentation xml:lang="en">

Added: db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingInterface.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingInterface.java?rev=1447627&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingInterface.java (added)
+++ db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingInterface.java Tue Feb 19 08:49:59 2013
@@ -0,0 +1,41 @@
+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.
+ */
+
+import java.sql.Connection;
+
+import org.apache.torque.om.ObjectKey;
+
+public interface OptimisticLockingInterface
+{
+    public String getName();
+
+    public void setName(String name);
+
+    public Integer getVersion();
+
+    public void save() throws TorqueException;
+
+    public void save(Connection connection) throws TorqueException;
+
+    ObjectKey getPrimaryKey();
+
+    boolean isModified();
+}

Added: db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingPeerInterface.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingPeerInterface.java?rev=1447627&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingPeerInterface.java (added)
+++ db/torque/torque4/trunk/torque-test/src/main/java/org/apache/torque/OptimisticLockingPeerInterface.java Tue Feb 19 08:49:59 2013
@@ -0,0 +1,43 @@
+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.
+ */
+
+import java.sql.Connection;
+import java.util.List;
+
+import org.apache.torque.criteria.Criteria;
+import org.apache.torque.om.ObjectKey;
+
+public interface OptimisticLockingPeerInterface<T>
+{
+    public int doUpdate(T toUpdate) throws TorqueException;
+
+    public int doUpdate(T toUpdate, Connection con) throws TorqueException;
+
+    T doSelectSingleRecord(T toSelect) throws TorqueException;
+
+    T retrieveByPK(ObjectKey key) throws TorqueException;
+
+    public int doDelete(T toDelete) throws TorqueException;
+
+    public int doDelete(Criteria criteria) throws TorqueException;
+
+    public List<T> doSelect(Criteria criteria) throws TorqueException;
+}

Modified: db/torque/torque4/trunk/torque-test/src/main/schema/test-schema.xml
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/main/schema/test-schema.xml?rev=1447627&r1=1447626&r2=1447627&view=diff
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/main/schema/test-schema.xml (original)
+++ db/torque/torque4/trunk/torque-test/src/main/schema/test-schema.xml Tue Feb 19 08:49:59 2013
@@ -132,4 +132,21 @@
     <column name="id" javaName="ID" primaryKey="true" type="INTEGER" />
     <column name="name" javaName="Name" type="VARCHAR" size="50" />
   </table>
+
+  <table name="optimistic_locking" 
+      interface="org.apache.torque.OptimisticLockingInterface"
+      peerInterface="org.apache.torque.OptimisticLockingPeerInterface&lt;org.apache.torque.test.dbobject.OptimisticLocking&gt;"
+      description="this table implements optimistic Locking with the selectForUpdate mode">
+    <column name="id" primaryKey="true" type="INTEGER" />
+    <column name="name" type="VARCHAR" size="50" />
+    <column name="version" type="INTEGER" version="true" javaType="object"/>
+  </table>
+  <table name="optimistic_locking_simple" optimisticLockingMode="simpleSelect"
+      interface="org.apache.torque.OptimisticLockingInterface"
+      peerInterface="org.apache.torque.OptimisticLockingPeerInterface&lt;org.apache.torque.test.dbobject.OptimisticLockingSimple&gt;"
+      description="this table implements optimistic Locking with the simple select mode">
+    <column name="id" primaryKey="true" type="INTEGER" />
+    <column name="name" type="VARCHAR" size="50" />
+    <column name="version" type="INTEGER" version="true" javaType="object"/>
+  </table>
 </database>

Added: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/BaseOptimisticLockingTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/BaseOptimisticLockingTest.java?rev=1447627&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/BaseOptimisticLockingTest.java (added)
+++ db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/BaseOptimisticLockingTest.java Tue Feb 19 08:49:59 2013
@@ -0,0 +1,289 @@
+package org.apache.torque.generated.peer;
+
+/*
+ * 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.Connection;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.torque.BaseDatabaseTestCase;
+import org.apache.torque.OptimisticLockingFailedException;
+import org.apache.torque.OptimisticLockingInterface;
+import org.apache.torque.OptimisticLockingPeerInterface;
+import org.apache.torque.Torque;
+import org.apache.torque.TorqueException;
+import org.apache.torque.criteria.Criteria;
+
+/**
+ * Tests whether optimistic locking works.
+ *
+ * @version $Id$
+ */
+public abstract class BaseOptimisticLockingTest<T extends OptimisticLockingInterface> extends BaseDatabaseTestCase
+{
+    OptimisticLockingPeerInterface<T> peer;
+
+    public BaseOptimisticLockingTest(OptimisticLockingPeerInterface<T> peer)
+    {
+        this.peer = peer;
+    }
+
+    /**
+     * Tests whether we can update an optimistically locked table.
+     *
+     * @throws Exception if a database error occurs.
+     */
+    public void testSave() throws Exception
+    {
+        // prepare
+        List<T> objectList = fillDatabase();
+
+        T toUpdate = objectList.get(1);
+        assertEquals(new Integer(0), toUpdate.getVersion());
+
+        toUpdate.setName("2a");
+
+        // execute
+        toUpdate.save();
+
+        // verify
+        assertEquals(new Integer(1), toUpdate.getVersion());
+        assertEquals("2a", toUpdate.getName());
+        assertDatabase(objectList);
+    }
+
+    /**
+     * Tests whether we can save an optimistically locked table
+     * with a connection.
+     *
+     * @throws Exception if a database error occurs.
+     */
+    public void testSaveWithConnection() throws Exception
+    {
+        // prepare
+        List<T> objectList = fillDatabase();
+
+        T toUpdate = objectList.get(1);
+        assertEquals(new Integer(0), toUpdate.getVersion());
+
+        toUpdate.setName("2a");
+        Connection connection = Torque.getConnection();
+
+        // execute
+        toUpdate.save(connection);
+
+        // cleanup
+        connection.close();
+
+        // verify
+        assertEquals(new Integer(1), toUpdate.getVersion());
+        assertEquals("2a", toUpdate.getName());
+        assertDatabase(objectList);
+    }
+
+    /**
+     * Tests whether we can update an optimistically locked table.
+     *
+     * @throws Exception if a database error occurs.
+     */
+    public void testUpdate() throws Exception
+    {
+        // prepare
+        List<T> objectList = fillDatabase();
+
+        T toUpdate = objectList.get(1);
+        assertEquals(new Integer(0), toUpdate.getVersion());
+
+        toUpdate.setName("2a");
+
+        // execute
+        peer.doUpdate(toUpdate);
+
+        // verify
+        assertEquals(new Integer(1), toUpdate.getVersion());
+        assertEquals("2a", toUpdate.getName());
+        assertDatabase(objectList);
+    }
+
+    /**
+     * Tests whether we can update an optimistically locked table
+     * with passing a connection.
+     *
+     * @throws Exception if a database error occurs.
+     */
+    public void testUpdateWithConnection() throws Exception
+    {
+        // prepare
+        List<T> objectList = fillDatabase();
+
+        T toUpdate = objectList.get(1);
+        assertEquals(new Integer(0), toUpdate.getVersion());
+
+        toUpdate.setName("2a");
+        Connection connection = Torque.getConnection();
+
+        // execute
+        peer.doUpdate(toUpdate, connection);
+
+        // cleanup
+        connection.close();
+
+        // verify
+        assertEquals(new Integer(1), toUpdate.getVersion());
+        assertEquals("2a", toUpdate.getName());
+        assertDatabase(objectList);
+    }
+
+    /**
+     * Tests whether we can save an optimistically locked table twice.
+     *
+     * @throws Exception if a database error occurs.
+     */
+    public void testSaveTwice() throws Exception
+    {
+        // prepare
+        List<T> objectList = fillDatabase();
+
+        T toUpdate = objectList.get(1);
+        assertEquals(new Integer(0), toUpdate.getVersion());
+
+        toUpdate.setName("2a");
+        toUpdate.save();
+        assertEquals(new Integer(1), toUpdate.getVersion());
+
+        toUpdate.setName("2b");
+
+        // execute
+        toUpdate.save();
+
+        // verify
+        assertEquals(new Integer(2), toUpdate.getVersion());
+        assertEquals("2b", toUpdate.getName());
+        assertDatabase(objectList);
+    }
+
+    /**
+     * Tests whether optimistic locking fails if the row has been updated
+     * by another access.
+     *
+     * @throws Exception if a database error occurs.
+     */
+    public void testOptimisticLockFailsOtherUpdate() throws Exception
+    {
+        // prepare
+        List<T> objectList = fillDatabase();
+
+        T concurrentUpdated = objectList.get(1);
+        T toUpdate = peer.doSelectSingleRecord(concurrentUpdated);
+
+        concurrentUpdated.setName("2a");
+        concurrentUpdated.save();
+
+        toUpdate.setName("2b");
+
+        // execute
+        try
+        {
+            toUpdate.save();
+            fail("Exception excpected");
+        }
+        catch (OptimisticLockingFailedException e)
+        {
+            // expected
+        }
+
+        // verify
+        assertEquals(new Integer(0), toUpdate.getVersion());
+        assertEquals("2b", toUpdate.getName());
+        assertTrue(toUpdate.isModified());
+        assertDatabase(objectList);
+    }
+
+    /**
+     * Tests whether optimistic locking fails if the row has been deleted
+     * by another access.
+     *
+     * @throws Exception if a database error occurs.
+     */
+    public void testOptimisticLockFailsOtherDelete() throws Exception
+    {
+        // prepare
+        List<T> objectList = fillDatabase();
+
+        T concurrentDeleted = objectList.remove(1);
+        T toUpdate = peer.doSelectSingleRecord(concurrentDeleted);
+
+        peer.doDelete(concurrentDeleted);
+
+        toUpdate.setName("2b");
+
+        // execute
+        try
+        {
+            toUpdate.save();
+            fail("Exception excpected");
+        }
+        catch (OptimisticLockingFailedException e)
+        {
+            // expected
+        }
+
+        // verify
+        assertEquals(new Integer(0), toUpdate.getVersion());
+        assertEquals("2b", toUpdate.getName());
+        assertTrue(toUpdate.isModified());
+        assertDatabase(objectList);
+    }
+
+    private List<T> fillDatabase() throws TorqueException
+    {
+        List<T> result = new ArrayList<T>();
+        peer.doDelete(new Criteria());
+        T optimisticLocking = newObject();
+        optimisticLocking.setName("1");
+        optimisticLocking.save();
+        result.add(optimisticLocking);
+        optimisticLocking = newObject();
+        optimisticLocking.setName("2");
+        optimisticLocking.save();
+        result.add(optimisticLocking);
+        optimisticLocking = newObject();
+        optimisticLocking.setName("3");
+        optimisticLocking.save();
+        result.add(optimisticLocking);
+        return result;
+    }
+
+    private void assertDatabase(List<T> expected)
+            throws TorqueException
+    {
+        assertEquals(
+                expected.size(),
+                peer.doSelect(new Criteria()).size());
+        for (T expectedElement : expected)
+        {
+            T actual = peer.retrieveByPK(expectedElement.getPrimaryKey());
+            assertEquals(expectedElement.getName(), actual.getName());
+            assertEquals(expectedElement.getVersion(), actual.getVersion());
+        }
+    }
+
+    public abstract T newObject();
+}

Propchange: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/BaseOptimisticLockingTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSelectForUpdateTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSelectForUpdateTest.java?rev=1447627&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSelectForUpdateTest.java (added)
+++ db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSelectForUpdateTest.java Tue Feb 19 08:49:59 2013
@@ -0,0 +1,41 @@
+package org.apache.torque.generated.peer;
+
+/*
+ * 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 org.apache.torque.test.dbobject.OptimisticLocking;
+import org.apache.torque.test.peer.OptimisticLockingPeerImpl;
+
+/**
+ * Tests whether optimistic locking with select for update works.
+ *
+ * @version $Id$
+ */
+public class OptimisticLockingSelectForUpdateTest extends BaseOptimisticLockingTest<OptimisticLocking>
+{
+    public OptimisticLockingSelectForUpdateTest()
+    {
+        super(new OptimisticLockingPeerImpl());
+    }
+
+    public OptimisticLocking newObject()
+    {
+        return new OptimisticLocking();
+    }
+}

Propchange: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSelectForUpdateTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision

Added: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSimpleSelectTest.java
URL: http://svn.apache.org/viewvc/db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSimpleSelectTest.java?rev=1447627&view=auto
==============================================================================
--- db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSimpleSelectTest.java (added)
+++ db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSimpleSelectTest.java Tue Feb 19 08:49:59 2013
@@ -0,0 +1,41 @@
+package org.apache.torque.generated.peer;
+
+/*
+ * 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 org.apache.torque.test.dbobject.OptimisticLockingSimple;
+import org.apache.torque.test.peer.OptimisticLockingSimplePeerImpl;
+
+/**
+ * Tests whether optimistic locking with select for update works.
+ *
+ * @version $Id$
+ */
+public class OptimisticLockingSimpleSelectTest extends BaseOptimisticLockingTest<OptimisticLockingSimple>
+{
+    public OptimisticLockingSimpleSelectTest()
+    {
+        super(new OptimisticLockingSimplePeerImpl());
+    }
+
+    public OptimisticLockingSimple newObject()
+    {
+        return new OptimisticLockingSimple();
+    }
+}

Propchange: db/torque/torque4/trunk/torque-test/src/test/java/org/apache/torque/generated/peer/OptimisticLockingSimpleSelectTest.java
------------------------------------------------------------------------------
    svn:keywords = Author Date Id Revision



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