Skip to content

Commit 7e18267

Browse files
author
Mike Mannion
committed
HHH-19497 Test for composition of 'not' 'in' restrictions. At this time, this test fails for dialects that do not support record-level construction, such as DB2Dialect.
1 parent f07a6f4 commit 7e18267

File tree

3 files changed

+198
-0
lines changed

3 files changed

+198
-0
lines changed
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.jpa.criteria.basic;
6+
import jakarta.persistence.Entity;
7+
import jakarta.persistence.Id;
8+
import jakarta.persistence.JoinColumn;
9+
import jakarta.persistence.JoinColumns;
10+
import jakarta.persistence.ManyToOne;
11+
12+
import java.util.Objects;
13+
14+
/**
15+
* Entity used in <code>org.hibernate.orm.test.jpa.criteria.basic.NegatedInPredicateTest</code>.
16+
*
17+
* @author Mike Mannion
18+
*/
19+
@Entity
20+
public class Foo {
21+
22+
@Id
23+
Long id;
24+
25+
@ManyToOne
26+
@JoinColumns({
27+
@JoinColumn(name = "FK_CODE", referencedColumnName = "CODE"),
28+
@JoinColumn(name = "FK_CONTEXT", referencedColumnName = "CONTEXT")
29+
})
30+
FooType fooType;
31+
32+
public Foo() {
33+
// For JPA
34+
}
35+
36+
public Foo(Long id, FooType fooType) {
37+
this.id = id;
38+
this.fooType = fooType;
39+
}
40+
41+
@Override
42+
public boolean equals(Object o) {
43+
if (o == null || getClass() != o.getClass()) return false;
44+
45+
Foo customer = (Foo) o;
46+
return Objects.equals(id, customer.id) && Objects.equals(fooType, customer.fooType);
47+
}
48+
49+
@Override
50+
public int hashCode() {
51+
int result = Objects.hashCode(id);
52+
result = 31 * result + Objects.hashCode(fooType);
53+
return result;
54+
}
55+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.jpa.criteria.basic;
6+
import jakarta.persistence.Column;
7+
import jakarta.persistence.Entity;
8+
import jakarta.persistence.Id;
9+
10+
/**
11+
* Entity used in <code>org.hibernate.orm.test.jpa.criteria.basic.NegatedInPredicateTest</code>.
12+
*
13+
* @author Mike Mannion
14+
*/
15+
@Entity
16+
public class FooType {
17+
@Id
18+
@Column(name = "CODE")
19+
String code;
20+
21+
@Column(name = "CONTEXT")
22+
String context;
23+
24+
public FooType() {
25+
// For JPA
26+
}
27+
28+
FooType(String code, String context) {
29+
this.code = code;
30+
this.context = context;
31+
}
32+
}
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.orm.test.jpa.criteria.basic;
6+
7+
import jakarta.persistence.criteria.CriteriaBuilder;
8+
import jakarta.persistence.criteria.CriteriaQuery;
9+
import jakarta.persistence.criteria.Root;
10+
import org.hibernate.testing.orm.junit.DomainModel;
11+
import org.hibernate.testing.orm.junit.JiraKey;
12+
import org.hibernate.testing.orm.junit.SessionFactory;
13+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
14+
import org.junit.jupiter.api.AfterEach;
15+
import org.junit.jupiter.api.BeforeEach;
16+
import org.junit.jupiter.api.Test;
17+
18+
import java.util.List;
19+
20+
import static org.assertj.core.api.Assertions.assertThat;
21+
22+
23+
/**
24+
* Add test which composes not with in. Test introduced after discovery the negated in
25+
* fails under dialects without record-level construction, such as DB2.
26+
*
27+
* @author Mike Mannion
28+
*/
29+
@JiraKey(value = "HHH-19497")
30+
@DomainModel(
31+
annotatedClasses = {Foo.class, FooType.class}
32+
)
33+
@SessionFactory
34+
class NegatedInPredicateTest {
35+
36+
public static final FooType FOO_TYPE1 = new FooType( "ft1", "ctx1" );
37+
public static final FooType FOO_TYPE2 = new FooType( "ft2", "ctx1" );
38+
39+
@BeforeEach
40+
void setup(SessionFactoryScope scope) {
41+
scope.inTransaction(
42+
em -> {
43+
em.persist( FOO_TYPE1 );
44+
em.persist( FOO_TYPE2 );
45+
46+
Foo foo1 = new Foo( 1L, FOO_TYPE1 );
47+
Foo foo2 = new Foo( 2L, FOO_TYPE1 );
48+
Foo foo3 = new Foo( 3L, FOO_TYPE2 );
49+
50+
em.persist( foo1 );
51+
em.persist( foo2 );
52+
em.persist( foo3 );
53+
}
54+
);
55+
}
56+
57+
@AfterEach
58+
void tearDown(SessionFactoryScope scope) {
59+
scope.inTransaction(
60+
em -> {
61+
em.createQuery( "delete from Foo" ).executeUpdate();
62+
em.createQuery( "delete from FooType" ).executeUpdate();
63+
}
64+
);
65+
}
66+
67+
@Test
68+
void testSanity(SessionFactoryScope scope) {
69+
scope.inTransaction(
70+
em -> {
71+
CriteriaBuilder cb = em.getCriteriaBuilder();
72+
CriteriaQuery<Foo> cq = cb.createQuery( Foo.class );
73+
Root<Foo> root = cq.from( Foo.class );
74+
assertThat( em.createQuery( cq.select( root ) ).getResultList() )
75+
.hasSize( 3 );
76+
}
77+
);
78+
}
79+
80+
@Test
81+
void testNegatedPredicate(SessionFactoryScope scope) {
82+
scope.inTransaction(
83+
em -> {
84+
CriteriaBuilder cb = em.getCriteriaBuilder();
85+
CriteriaQuery<Foo> cq = cb.createQuery( Foo.class );
86+
Root<Foo> root = cq.from( Foo.class );
87+
cq.select( root )
88+
.where( cb.not( root.get( "fooType" ).in( List.of( FOO_TYPE1, FOO_TYPE2 ) ) ) );
89+
assertThat( em.createQuery( cq ).getResultList() )
90+
.isEmpty();
91+
}
92+
);
93+
}
94+
95+
@Test
96+
void testNonNegatedInPredicate(SessionFactoryScope scope) {
97+
scope.inTransaction(
98+
em -> {
99+
CriteriaBuilder cb = em.getCriteriaBuilder();
100+
CriteriaQuery<Foo> cq = cb.createQuery( Foo.class );
101+
Root<Foo> root = cq.from( Foo.class );
102+
cq.select( root )
103+
.where( root.get( "fooType" ).in( List.of( FOO_TYPE1, FOO_TYPE2 ) ) );
104+
assertThat( em.createQuery( cq ).getResultList() )
105+
.hasSize( 3 );
106+
107+
}
108+
);
109+
}
110+
111+
}

0 commit comments

Comments
 (0)