Skip to content

Commit

Permalink
Bug 579726: CriteriaBuilder neg() only returns Integer type.
Browse files Browse the repository at this point in the history
Signed-off-by: Joe Grassel <[email protected]>
  • Loading branch information
jgrassel committed Apr 22, 2022
1 parent 4fd7165 commit f5b5422
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// 04/19/2022: Jody Grassel
// - Issue 579726: CriteriaBuilder neg() only returns Integer type, instead of it's argument expression type.
package org.eclipse.persistence.jpa.test.criteria;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Expression;
import jakarta.persistence.criteria.Root;
import jakarta.persistence.criteria.Selection;

import org.eclipse.persistence.jpa.test.criteria.model.CoalesceEntity;
import org.eclipse.persistence.jpa.test.criteria.model.CritEntity;
import org.eclipse.persistence.jpa.test.framework.DDLGen;
import org.eclipse.persistence.jpa.test.framework.Emf;
import org.eclipse.persistence.jpa.test.framework.EmfRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(EmfRunner.class)
public class TestNegFunction {
@Emf(createTables = DDLGen.DROP_CREATE, classes = { CritEntity.class })
private EntityManagerFactory emf;

@Test
public void testNegFunction() throws Exception {
EntityManager em = emf.createEntityManager();

try {
CritEntity ce = new CritEntity();
ce.setId(1);
ce.setValue(new BigDecimal("3.14"));

em.getTransaction().begin();
em.persist(ce);;
em.getTransaction().commit();
em.clear();

CriteriaBuilder criteriaBuilder = em.getCriteriaBuilder();
CriteriaQuery<DecHolder> criteriaQuery = criteriaBuilder.createQuery(DecHolder.class);
Root<CritEntity> entityRoot = criteriaQuery.from(CritEntity.class);

Collection<Selection<?>> selections = new ArrayList<Selection<?>>();

Expression<BigDecimal> valExpr = entityRoot.get("value");

selections.add(criteriaBuilder.sum(
criteriaBuilder.<BigDecimal> selectCase()
.when(criteriaBuilder.equal(entityRoot.get("id"), 0), valExpr)
.otherwise(criteriaBuilder.neg(valExpr))));

criteriaQuery.multiselect(selections.toArray(new Selection[] {}));

List<DecHolder> retList = em.createQuery(criteriaQuery).getResultList();
} finally {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
if(em.isOpen()) {
em.close();
}
}
}

public static class DecHolder {
private BigDecimal value;

public DecHolder(Object value) {
super();
this.value = (BigDecimal) value;
}

public BigDecimal getValue() {
return value;
}

public void setValue(BigDecimal value) {
this.value = value;
}

@Override
public String toString() {
return "DecHolder [value=" + value + "]";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2022 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// 04/19/2022: Jody Grassel
// - Issue 579726: CriteriaBuilder neg() only returns Integer type, instead of it's argument expression type.
package org.eclipse.persistence.jpa.test.criteria.model;

import java.math.BigDecimal;

import jakarta.persistence.Basic;
import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;

@Entity
public class CritEntity {
@Id
private int id;

@Basic
@Column(precision = 10, scale = 2)
private BigDecimal value;

public CritEntity() {

}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public BigDecimal getValue() {
return value;
}

public void setValue(BigDecimal bigDec) {
this.value = bigDec;
}

@Override
public String toString() {
return "CritEntity [id=" + id + ", value=" + value + "]";
}


}


Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
// Contributors:
// Gordon Yorke - Initial development
//
// Contributors:
// 04/19/2022: Jody Grassel
// - Issue 579726: CriteriaBuilder neg() only returns Integer type, instead of it's argument expression type.
package org.eclipse.persistence.internal.jpa.querydef;

import java.io.Serializable;
Expand Down Expand Up @@ -650,7 +653,7 @@ public Predicate equal(Expression<?> x, Object y){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
if (y instanceof ParameterExpression)
if (y instanceof ParameterExpression)
return this.equal(x, (ParameterExpression)y);

return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().equal(y), buildList(x, internalLiteral(y)), "equal");
Expand All @@ -670,7 +673,7 @@ public Predicate notEqual(Expression<?> x, Object y){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
if (y instanceof ParameterExpression)
if (y instanceof ParameterExpression)
return this.notEqual(x, (ParameterExpression)y);

return new CompoundExpressionImpl(this.metamodel, ((InternalSelection)x).getCurrentNode().notEqual(y), buildList(x, internalLiteral(y)), "not equal");
Expand Down Expand Up @@ -999,7 +1002,7 @@ public Predicate le(Expression<? extends Number> x, Number y){
*/
@Override
public <N extends Number> Expression<N> neg(Expression<N> x){
return new FunctionExpressionImpl(this.metamodel, ClassConstants.INTEGER, ExpressionMath.negate(((InternalSelection)x).getCurrentNode()), buildList(x), "neg");
return new FunctionExpressionImpl(this.metamodel, (Class<N>) x.getJavaType(), ExpressionMath.negate(((InternalSelection)x).getCurrentNode()), buildList(x), "neg");
}

/**
Expand Down

0 comments on commit f5b5422

Please sign in to comment.