Skip to content

Commit 5ca841c

Browse files
committed
HHH-18321 Add test for issue
1 parent 26495fb commit 5ca841c

File tree

1 file changed

+102
-40
lines changed

1 file changed

+102
-40
lines changed

hibernate-core/src/test/java/org/hibernate/orm/test/jpa/criteria/CoalesceTest.java

Lines changed: 102 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,29 +4,43 @@
44
*/
55
package org.hibernate.orm.test.jpa.criteria;
66

7+
import java.math.BigDecimal;
8+
import java.util.List;
9+
710
import org.hibernate.testing.orm.junit.JiraKey;
811
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
12+
import org.hibernate.testing.orm.junit.Jira;
913
import org.hibernate.testing.orm.junit.Jpa;
1014

15+
import org.junit.jupiter.api.AfterAll;
16+
import org.junit.jupiter.api.BeforeAll;
1117
import org.junit.jupiter.api.Test;
1218

1319
import jakarta.persistence.Column;
20+
import jakarta.persistence.Embeddable;
21+
import jakarta.persistence.Embedded;
1422
import jakarta.persistence.Entity;
1523
import jakarta.persistence.Id;
24+
import jakarta.persistence.Tuple;
1625
import jakarta.persistence.TypedQuery;
1726
import jakarta.persistence.criteria.CriteriaBuilder;
1827
import jakarta.persistence.criteria.CriteriaQuery;
1928
import jakarta.persistence.criteria.Expression;
2029
import jakarta.persistence.criteria.ParameterExpression;
2130
import jakarta.persistence.criteria.Root;
2231

32+
import static org.assertj.core.api.Assertions.assertThat;
33+
2334
/**
2435
* @author Will Dazy
2536
*/
26-
@Jpa(annotatedClasses = CoalesceTest.HHH15291Entity.class)
37+
@Jpa( annotatedClasses = {
38+
CoalesceTest.HHH15291Entity.class,
39+
CoalesceTest.ComponentEntity.class,
40+
CoalesceTest.ComponentA.class,
41+
} )
2742
@JiraKey( value = "HHH-15291")
2843
public class CoalesceTest {
29-
3044
@Test
3145
public void hhh15291JPQL1Test(EntityManagerFactoryScope scope) {
3246
scope.inEntityManager(
@@ -95,9 +109,74 @@ public void hhh15291Criteria2Test(EntityManagerFactoryScope scope) {
95109
);
96110
}
97111

112+
@Test
113+
@Jira( "https://hibernate.atlassian.net/browse/HHH-18321" )
114+
public void testCoalesceInBinaryArithmetic(EntityManagerFactoryScope scope) {
115+
scope.inTransaction( entityManager -> {
116+
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
117+
final CriteriaQuery<Tuple> cquery = cb.createTupleQuery();
118+
final Root<ComponentEntity> root = cquery.from( ComponentEntity.class );
119+
120+
cquery.select( cb.tuple(
121+
root.get( "id" ),
122+
cb.diff(
123+
cb.coalesce( root.get( "componentA" ).get( "income" ), BigDecimal.ZERO ),
124+
cb.coalesce( root.get( "componentA" ).get( "expense" ), BigDecimal.ZERO )
125+
)
126+
) );
127+
128+
final List<Tuple> resultList = entityManager.createQuery( cquery ).getResultList();
129+
assertThat( resultList ).hasSize( 2 );
130+
for ( Tuple result : resultList ) {
131+
final Long id = result.get( 0, Long.class );
132+
assertThat( result.get( 1, BigDecimal.class ).intValue() ).isEqualTo( id == 1L ? 0 : 1 );
133+
}
134+
} );
135+
}
136+
137+
@Test
138+
@Jira( "https://hibernate.atlassian.net/browse/HHH-18321" )
139+
public void testCoalesceInBinaryArithmeticParam(EntityManagerFactoryScope scope) {
140+
scope.inTransaction( entityManager -> {
141+
final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
142+
final CriteriaQuery<Tuple> cquery = cb.createTupleQuery();
143+
final Root<ComponentEntity> root = cquery.from( ComponentEntity.class );
144+
145+
final ParameterExpression<BigDecimal> defaultValue = cb.parameter( BigDecimal.class, "default-value" );
146+
147+
cquery.select( cb.tuple(
148+
root.get( "id" ),
149+
cb.diff(
150+
defaultValue,
151+
cb.coalesce( root.get( "componentA" ).get( "expense" ), defaultValue )
152+
)
153+
) );
154+
155+
final List<Tuple> resultList = entityManager.createQuery( cquery )
156+
.setParameter( "default-value", BigDecimal.ZERO ).getResultList();
157+
assertThat( resultList ).hasSize( 2 );
158+
for ( Tuple result : resultList ) {
159+
final Long id = result.get( 0, Long.class );
160+
assertThat( result.get( 1, BigDecimal.class ).intValue() ).isEqualTo( id == 1L ? -1 : 0 );
161+
}
162+
} );
163+
}
164+
165+
@BeforeAll
166+
public void setUp(EntityManagerFactoryScope scope) {
167+
scope.inTransaction( entityManager -> {
168+
entityManager.persist( new ComponentEntity( 1L, new ComponentA( BigDecimal.ONE, BigDecimal.ONE ) ) );
169+
entityManager.persist( new ComponentEntity( 2L, new ComponentA( BigDecimal.ONE, null ) ) );
170+
} );
171+
}
172+
173+
@AfterAll
174+
public void tearDown(EntityManagerFactoryScope scope) {
175+
scope.inTransaction( entityManager -> entityManager.createQuery( "delete from ComponentEntity" ).executeUpdate() );
176+
}
177+
98178
@Entity(name = "HHH15291Entity")
99179
public static class HHH15291Entity {
100-
101180
@Id
102181
@Column(name = "KEY_CHAR")
103182
private String KeyString;
@@ -116,53 +195,36 @@ public static class HHH15291Entity {
116195

117196
@Column(name = "ITEM_INTEGER1")
118197
private Integer itemInteger1;
198+
}
119199

120-
public String getKeyString() {
121-
return KeyString;
122-
}
123-
124-
public void setKeyString(String keyString) {
125-
KeyString = keyString;
126-
}
127-
128-
public String getItemString1() {
129-
return itemString1;
130-
}
131-
132-
public void setItemString1(String itemString1) {
133-
this.itemString1 = itemString1;
134-
}
135-
136-
public String getItemString2() {
137-
return itemString2;
138-
}
139-
140-
public void setItemString2(String itemString2) {
141-
this.itemString2 = itemString2;
142-
}
200+
@Entity( name = "ComponentEntity" )
201+
static class ComponentEntity {
202+
@Id
203+
private Long id;
143204

144-
public String getItemString3() {
145-
return itemString3;
146-
}
205+
@Embedded
206+
private ComponentA componentA;
147207

148-
public void setItemString3(String itemString3) {
149-
this.itemString3 = itemString3;
208+
public ComponentEntity() {
150209
}
151210

152-
public String getItemString4() {
153-
return itemString4;
211+
public ComponentEntity(Long id, ComponentA componentA) {
212+
this.id = id;
213+
this.componentA = componentA;
154214
}
215+
}
155216

156-
public void setItemString4(String itemString4) {
157-
this.itemString4 = itemString4;
158-
}
217+
@Embeddable
218+
static class ComponentA {
219+
private BigDecimal income;
220+
private BigDecimal expense;
159221

160-
public Integer getItemInteger1() {
161-
return itemInteger1;
222+
public ComponentA() {
162223
}
163224

164-
public void setItemInteger1(Integer itemInteger1) {
165-
this.itemInteger1 = itemInteger1;
225+
public ComponentA(BigDecimal income, BigDecimal expense) {
226+
this.income = income;
227+
this.expense = expense;
166228
}
167229
}
168230
}

0 commit comments

Comments
 (0)