HHH-13216 Fix BigDecimal handling in criteria queries
We used to lose some precision when dealing with BigDecimals.
This commit is contained in:
parent
4e06de2708
commit
b843b3e033
|
@ -195,6 +195,12 @@ public class ValueHandlerFactory {
|
|||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
if ( BigInteger.class.isInstance( value ) ) {
|
||||
return (BigInteger) value;
|
||||
}
|
||||
if ( BigDecimal.class.isInstance( value ) ) {
|
||||
return ( (BigDecimal) value ).toBigInteger();
|
||||
}
|
||||
if ( Number.class.isInstance( value ) ) {
|
||||
return BigInteger.valueOf( ( (Number) value ).longValue() );
|
||||
}
|
||||
|
@ -216,6 +222,9 @@ public class ValueHandlerFactory {
|
|||
if ( value == null ) {
|
||||
return null;
|
||||
}
|
||||
if ( BigDecimal.class.isInstance( value ) ) {
|
||||
return (BigDecimal) value;
|
||||
}
|
||||
if ( BigInteger.class.isInstance( value ) ) {
|
||||
return new BigDecimal( (BigInteger) value );
|
||||
}
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||
*/
|
||||
package org.hibernate.test.type;
|
||||
|
||||
import org.hibernate.Session;
|
||||
import org.hibernate.query.Query;
|
||||
import org.hibernate.resource.transaction.spi.TransactionStatus;
|
||||
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import javax.persistence.Basic;
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.criteria.CriteriaBuilder;
|
||||
import javax.persistence.criteria.CriteriaQuery;
|
||||
import javax.persistence.criteria.Root;
|
||||
|
||||
/**
|
||||
* @author Ales Justin
|
||||
*/
|
||||
public class BigDecimalTypeTest extends BaseNonConfigCoreFunctionalTestCase {
|
||||
@Override
|
||||
protected Class[] getAnnotatedClasses() {
|
||||
return new Class[] {Account.class};
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBigDecimalInSum() {
|
||||
final BigDecimal balance = new BigDecimal("1000000000.00000004");
|
||||
|
||||
Session s = openSession();
|
||||
s.getTransaction().begin();
|
||||
try {
|
||||
Account account = new Account();
|
||||
account.id = 1L;
|
||||
account.balance = balance;
|
||||
|
||||
s.save( account );
|
||||
s.getTransaction().commit();
|
||||
}
|
||||
catch (Exception e) {
|
||||
if ( s.getTransaction() != null && s.getTransaction().getStatus() == TransactionStatus.ACTIVE ) {
|
||||
s.getTransaction().rollback();
|
||||
}
|
||||
fail( e.getMessage() );
|
||||
}
|
||||
finally {
|
||||
s.close();
|
||||
}
|
||||
|
||||
s = openSession();
|
||||
s.getTransaction().begin();
|
||||
try {
|
||||
CriteriaBuilder b = s.getCriteriaBuilder();
|
||||
|
||||
CriteriaQuery<BigDecimal> cq = b.createQuery(BigDecimal.class);
|
||||
Root<Account> account_ = cq.from(Account.class);
|
||||
|
||||
cq.select(b.sum(account_.get("balance")));
|
||||
|
||||
Query<BigDecimal> query = s.createQuery(cq);
|
||||
|
||||
BigDecimal result = s.createQuery("SELECT SUM(a.balance) FROM Account a", BigDecimal.class).uniqueResult();
|
||||
Assert.assertEquals(0, balance.compareTo(result));
|
||||
|
||||
result = query.uniqueResult();
|
||||
Assert.assertEquals(0, balance.compareTo(result));
|
||||
|
||||
s.getTransaction().commit();
|
||||
}
|
||||
catch (Exception e) {
|
||||
if ( s.getTransaction() != null && s.getTransaction().getStatus() == TransactionStatus.ACTIVE ) {
|
||||
s.getTransaction().rollback();
|
||||
}
|
||||
fail( e.getMessage() );
|
||||
}
|
||||
finally {
|
||||
s.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Entity(name = "Account")
|
||||
public static class Account {
|
||||
|
||||
@Id
|
||||
private Long id;
|
||||
|
||||
@Basic(optional = false)
|
||||
@Column(precision = 20, scale = 8)
|
||||
private BigDecimal balance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isCleanupTestDataRequired() {
|
||||
return true;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue