Author: gbadner
Date: 2010-05-10 18:18:47 -0400 (Mon, 10 May 2010)
New Revision: 19458
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/BinaryArithmeticOperation.java
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/basic/ExpressionsTest.java
Log:
HHH-5078 : JPA criteria query numeric expressions produce wrong result (due to wrong
bracketing)
Modified:
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/BinaryArithmeticOperation.java
===================================================================
---
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/BinaryArithmeticOperation.java 2010-05-10
22:11:45 UTC (rev 19457)
+++
core/trunk/entitymanager/src/main/java/org/hibernate/ejb/criteria/expression/BinaryArithmeticOperation.java 2010-05-10
22:18:47 UTC (rev 19458)
@@ -43,27 +43,27 @@
public static enum Operation {
ADD {
String apply(String lhs, String rhs) {
- return lhs + " + " + rhs;
+ return applyPrimitive( lhs, '+', rhs );
}
},
SUBTRACT {
String apply(String lhs, String rhs) {
- return lhs + " - " + rhs;
+ return applyPrimitive( lhs, '-', rhs );
}
},
MULTIPLY {
String apply(String lhs, String rhs) {
- return lhs + " * " + rhs;
+ return applyPrimitive( lhs, '*', rhs );
}
},
DIVIDE {
String apply(String lhs, String rhs) {
- return lhs + " / " + rhs;
+ return applyPrimitive( lhs, '/', rhs );
}
},
QUOT {
String apply(String lhs, String rhs) {
- return lhs + " / " + rhs;
+ return applyPrimitive( lhs, '/', rhs );
}
},
MOD {
@@ -73,6 +73,18 @@
}
};
abstract String apply(String lhs, String rhs);
+
+ private static final char LEFT_PAREN = '(';
+ private static final char RIGHT_PAREN = ')';
+ private static String applyPrimitive(String lhs, char operator, String rhs) {
+ return new StringBuffer( lhs.length() + rhs.length() + 3 )
+ .append( LEFT_PAREN )
+ .append( lhs )
+ .append( operator )
+ .append( rhs )
+ .append( RIGHT_PAREN )
+ .toString();
+ }
}
private final Operation operator;
Modified:
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/basic/ExpressionsTest.java
===================================================================
---
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/basic/ExpressionsTest.java 2010-05-10
22:11:45 UTC (rev 19457)
+++
core/trunk/entitymanager/src/test/java/org/hibernate/ejb/criteria/basic/ExpressionsTest.java 2010-05-10
22:18:47 UTC (rev 19458)
@@ -63,7 +63,7 @@
@Override
public void tearDown() throws Exception {
EntityManager em = getOrCreateEntityManager();
- em.getTransaction().begin();
+ em.getTransaction().begin();
em.createQuery( "delete Product" ).executeUpdate();
em.getTransaction().commit();
em.close();
@@ -153,4 +153,78 @@
em.getTransaction().commit();
em.close();
}
+
+ public void testDiffWithQuotient() {
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ CriteriaQuery<Number> criteria = builder.createQuery( Number.class );
+ criteria.from( Product.class );
+ criteria.select(
+ builder.quot(
+ builder.diff(
+ builder.literal( BigDecimal.valueOf( 2.0 ) ),
+ builder.literal( BigDecimal.valueOf( 1.0 ) )
+ ),
+ BigDecimal.valueOf( 2.0 )
+ )
+ );
+ Number result = em.createQuery( criteria ).getSingleResult();
+ assertEquals(0.5d, result.doubleValue(), 0.1d);
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ public void testSumWithQuotient() {
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ CriteriaQuery<Number> criteria = builder.createQuery( Number.class );
+ criteria.from( Product.class );
+ criteria.select(
+ builder.quot(
+ builder.sum(
+ builder.literal( BigDecimal.valueOf( 0.0 ) ),
+ builder.literal( BigDecimal.valueOf( 1.0 ) )
+ ),
+ BigDecimal.valueOf( 2.0 )
+ )
+ );
+ Number result = em.createQuery( criteria ).getSingleResult();
+ assertEquals(0.5d, result.doubleValue(), 0.1d);
+ em.getTransaction().commit();
+ em.close();
+ }
+
+ public void testQuotientAndMultiply() {
+ EntityManager em = getOrCreateEntityManager();
+ em.getTransaction().begin();
+ CriteriaQuery<Number> criteria = builder.createQuery( Number.class );
+ criteria.from( Product.class );
+ criteria.select(
+ builder.quot(
+ builder.prod(
+ builder.literal( BigDecimal.valueOf( 10.0 ) ),
+ builder.literal( BigDecimal.valueOf( 5.0 ) )
+ ),
+ BigDecimal.valueOf( 2.0 )
+ )
+ );
+ Number result = em.createQuery( criteria ).getSingleResult();
+ assertEquals(25.0d, result.doubleValue(), 0.1d);
+
+ criteria.select(
+ builder.prod(
+ builder.quot(
+ builder.literal( BigDecimal.valueOf( 10.0 ) ),
+ builder.literal( BigDecimal.valueOf( 5.0 ) )
+ ),
+ BigDecimal.valueOf( 2.0 )
+ )
+ );
+ result = em.createQuery( criteria ).getSingleResult();
+ assertEquals(4.0d, result.doubleValue(), 0.1d);
+
+ em.getTransaction().commit();
+ em.close();
+ }
+
}