You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by ht...@apache.org on 2013/10/04 21:35:55 UTC

svn commit: r1529273 - in /openjpa/branches/2.2.x: ./ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ openjpa-kernel/src/main/java/org/apache/openjpa/conf/ openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/ openjpa-pers...

Author: hthomann
Date: Fri Oct  4 19:35:54 2013
New Revision: 1529273

URL: http://svn.apache.org/r1529273
Log:
OPENJPA-1794: Return null, rather than 0, on MAX function - back ported to 2.2.x Jeremy Bauer's commit to trunk.

Added:
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NullableAggregateUnaryOp.java
      - copied unchanged from r1529267, openjpa/branches/2.2.1.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/NullableAggregateUnaryOp.java
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/
      - copied from r1529267, openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/AggEntity.java
      - copied unchanged from r1529267, openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/AggEntity.java
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/AggEntity_.java
      - copied unchanged from r1529267, openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/AggEntity_.java
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/TestAggregateFunctions.java
      - copied unchanged from r1529267, openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/TestAggregateFunctions.java
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/TestCompatAggregateFunctions.java
      - copied unchanged from r1529267, openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/jira1794/TestCompatAggregateFunctions.java
Modified:
    openjpa/branches/2.2.x/   (props changed)
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Avg.java
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Max.java
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Min.java
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java
    openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java
    openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
    openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/onetomany/   (props changed)
    openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml

Propchange: openjpa/branches/2.2.x/
------------------------------------------------------------------------------
  Merged /openjpa/branches/2.2.1.x:r1529267
  Merged /openjpa/branches/2.1.x:r1529241

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Avg.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Avg.java?rev=1529273&r1=1529272&r2=1529273&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Avg.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Avg.java Fri Oct  4 19:35:54 2013
@@ -23,8 +23,9 @@ package org.apache.openjpa.jdbc.kernel.e
  *
  * @author Abe White
  */
+@SuppressWarnings("serial")
 class Avg
-    extends UnaryOp {
+    extends NullableAggregateUnaryOp { // OPENJPA-1794
 
     /**
      * Constructor. Provide the value to operate on.
@@ -41,4 +42,3 @@ class Avg
         return true;
     }
 }
-

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Max.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Max.java?rev=1529273&r1=1529272&r2=1529273&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Max.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Max.java Fri Oct  4 19:35:54 2013
@@ -23,8 +23,9 @@ package org.apache.openjpa.jdbc.kernel.e
  *
  * @author Abe White
  */
+@SuppressWarnings("serial")
 class Max
-    extends UnaryOp {
+    extends NullableAggregateUnaryOp { // OPENJPA-1794
 
     /**
      * Constructor. Provide the value to operate on.

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Min.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Min.java?rev=1529273&r1=1529272&r2=1529273&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Min.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Min.java Fri Oct  4 19:35:54 2013
@@ -23,8 +23,9 @@ package org.apache.openjpa.jdbc.kernel.e
  *
  * @author Abe White
  */
+@SuppressWarnings("serial")
 class Min
-    extends UnaryOp {
+    extends NullableAggregateUnaryOp { // OPENJPA-1794
 
     /**
      * Constructor. Provide the value to operate on.

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java?rev=1529273&r1=1529272&r2=1529273&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Sum.java Fri Oct  4 19:35:54 2013
@@ -25,8 +25,9 @@ import org.apache.openjpa.kernel.Filters
  *
  * @author Abe White
  */
+@SuppressWarnings("serial")
 class Sum
-    extends UnaryOp {
+    extends NullableAggregateUnaryOp { // OPENJPA-1794
 
     /**
      * Constructor. Provide the value to operate on.

Modified: openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java?rev=1529273&r1=1529272&r2=1529273&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java (original)
+++ openjpa/branches/2.2.x/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java Fri Oct  4 19:35:54 2013
@@ -119,8 +119,13 @@ abstract class UnaryOp
         throws SQLException {
         Object value = res.getObject(this, JavaSQLTypes.JDBC_DEFAULT, null);
         Class<?> type = getType();
-        if (value == null && (type.isPrimitive() || Number.class.isAssignableFrom(type))) {
-            value = Filters.getDefaultForNull(Filters.wrap(type));
+        if (value == null) {
+            if (nullableValue(ctx, state)) {  // OPENJPA-1794
+                return null;
+            }
+            else if (type.isPrimitive() || Number.class.isAssignableFrom(type)) {
+                value = Filters.getDefaultForNull(Filters.wrap(type));
+            }
         }
         return Filters.convert(value, type);
     }
@@ -171,5 +176,10 @@ abstract class UnaryOp
         _val.acceptVisit(visitor);
         visitor.exit(this);
     }
-}
+    
+    // OPENJPA-1794
+    protected boolean nullableValue(ExpContext ctx, ExpState state) {
+        return false;
+    }
 
+}

Modified: openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?rev=1529273&r1=1529272&r2=1529273&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java (original)
+++ openjpa/branches/2.2.x/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java Fri Oct  4 19:35:54 2013
@@ -76,7 +76,9 @@ public class Compatibility {
     private boolean _resetFlushFlagForCascadePersist = true;//OPENJPA-2051
     private boolean _singletonLifecycleEventManager = false;
     private boolean _filterPCRegistryClasses = false; // OPENJPA-2288
-    
+    private boolean _useListAttributeForArrays = true;
+    private boolean _returnNullOnEmptyAggregateResult = false;   // OPENJPA-1794
+
     /**
      * Whether to require exact identity value types when creating object
      * ids from a class and value. Defaults to false.
@@ -728,4 +730,38 @@ public class Compatibility {
     public void setFilterPCRegistryClasses(boolean bool) {
         _filterPCRegistryClasses = bool;
     }
+
+    /**
+     * This property is used to specify whether the aggregate query functions 
+     * SUM, AVG, MAX, and MIN return null if there is no query result.  This will occur
+     * if no rows are returned for the specified query predicate. The default is 
+     * false, meaning that 0 will be returned for functions operating on numeric
+     * data.
+     * 
+     * In compliance with the JPA specification, the default value is true.
+     * 
+     * @return true if the result of an aggregate with an empty query result returns null.
+     * @since 
+     * 
+     */
+    public boolean getReturnNullOnEmptyAggregateResult() {
+        return _returnNullOnEmptyAggregateResult;
+    }
+
+    /**
+     * This property is used to specify whether the aggregate query functions 
+     * SUM, AVG, MAX, and MIN return null if there is no query result.  This will occur
+     * if no rows are returned for the specified query predicate. The default is 
+     * false, meaning that 0 will be returned for functions operating on numeric
+     * data.
+     * 
+     * In compliance with the JPA specification, the default value is true.
+     * 
+     * @since 
+     * @param returnNullOnAggregate whether OpenJPA will return null for aggregate
+     * expressions when the query result is empty.
+     */
+    public void setReturnNullOnAggregateResult(boolean returnNullOnEmptyAggregateResult) {
+        _returnNullOnEmptyAggregateResult = returnNullOnEmptyAggregateResult;
+    }
 }

Propchange: openjpa/branches/2.2.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/onetomany/
------------------------------------------------------------------------------
  Merged /openjpa/branches/2.2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/onetomany:r1529267
  Merged /openjpa/branches/2.1.x/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/inheritance/jointable/onetomany:r1529241

Modified: openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml
URL: http://svn.apache.org/viewvc/openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml?rev=1529273&r1=1529272&r2=1529273&view=diff
==============================================================================
--- openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml (original)
+++ openjpa/branches/2.2.x/openjpa-project/src/doc/manual/migration_considerations.xml Fri Oct  4 19:35:54 2013
@@ -511,6 +511,25 @@
                      details described in section <xref linkend="ref_guide_shared_cache_mode_integration"/>.
                 </para>
             </section>
+            <section id="ReturnNullOnEmptyAggregateResult">
+                <title>
+                    Return value of aggregate functions in SELECT clause 
+                </title>
+                <!-- See OPENJPA-1794 for details. -->
+                <para>
+                    The JPA specification states "If SUM, AVG, MAX, or MIN is used, and there are no values to which the aggregate function can be
+                    applied, the result of the aggregate function is NULL."  Prior to this update, OpenJPA incorrectly returned 0 for SUM, AVG, MIN, 
+                    and MAX when a state field being aggregated is numeric.  This behavior affects both JPQL and Criteria queries.  With this update,
+                    OpenJPA will return a null result value for these aggregate functions when a query returns no result.
+                </para>
+                <para>
+                    To enable the new behavior of this fix, you need to set the following persistence property in your persistence.xml or when
+                    creating an EntityManagerFactory.
+                    <programlisting>
+    &lt;property name="openjpa.Compatibility" value="ReturnNullOnAggregateResult=true"/&gt;
+                    </programlisting>
+                </para>
+            </section>            
         </section>
     </section>
 </appendix>