4
4
*/
5
5
package org .hibernate .orm .test .jpa .query ;
6
6
7
- import org .hibernate .testing .orm .junit .EntityManagerFactoryScope ;
8
- import org .hibernate .testing .orm .junit .Jpa ;
9
- import org .junit .jupiter .api .Test ;
10
-
11
7
import jakarta .persistence .Entity ;
8
+ import jakarta .persistence .GeneratedValue ;
12
9
import jakarta .persistence .Id ;
10
+ import jakarta .persistence .Lob ;
13
11
import jakarta .persistence .Query ;
14
12
import jakarta .persistence .criteria .CriteriaBuilder ;
15
13
import jakarta .persistence .criteria .CriteriaUpdate ;
14
+ import jakarta .persistence .criteria .Expression ;
16
15
import jakarta .persistence .criteria .ParameterExpression ;
16
+ import jakarta .persistence .criteria .Path ;
17
17
import jakarta .persistence .criteria .Root ;
18
18
import jakarta .persistence .metamodel .EntityType ;
19
+ import org .hibernate .query .criteria .HibernateCriteriaBuilder ;
20
+ import org .hibernate .testing .orm .junit .EntityManagerFactoryScope ;
21
+ import org .hibernate .testing .orm .junit .Jpa ;
22
+ import org .junit .jupiter .api .Test ;
19
23
20
- @ Jpa (
21
- annotatedClasses = CriteriaUpdateWithParametersTest .Person .class
22
- )
24
+
25
+ @ Jpa (annotatedClasses = {
26
+ CriteriaUpdateWithParametersTest .Person .class ,
27
+ CriteriaUpdateWithParametersTest .Process .class
28
+ })
23
29
public class CriteriaUpdateWithParametersTest {
24
30
25
31
@ Test
26
32
public void testCriteriaUpdate (EntityManagerFactoryScope scope ) {
27
- scope .inTransaction (
28
- entityManager -> {
29
- final CriteriaBuilder criteriaBuilder = entityManager .getCriteriaBuilder ();
30
- final CriteriaUpdate <Person > criteriaUpdate = criteriaBuilder .createCriteriaUpdate ( Person .class );
31
- final Root <Person > root = criteriaUpdate .from ( Person .class );
32
-
33
- final ParameterExpression <Integer > intValueParameter = criteriaBuilder .parameter ( Integer .class );
34
- final ParameterExpression <String > stringValueParameter = criteriaBuilder .parameter ( String .class );
35
-
36
- final EntityType <Person > personEntityType = entityManager .getMetamodel ().entity ( Person .class );
37
-
38
- criteriaUpdate .set (
39
- root .get ( personEntityType .getSingularAttribute ( "age" , Integer .class ) ),
40
- intValueParameter
41
- );
42
- criteriaUpdate .where ( criteriaBuilder .equal (
43
- root .get ( personEntityType .getSingularAttribute ( "name" , String .class ) ),
44
- stringValueParameter
45
- ) );
46
-
47
- final Query query = entityManager .createQuery ( criteriaUpdate );
48
- query .setParameter ( intValueParameter , 9 );
49
- query .setParameter ( stringValueParameter , "Luigi" );
50
-
51
- query .executeUpdate ();
52
- }
53
- );
33
+ scope .inTransaction ( entityManager -> {
34
+ final CriteriaBuilder criteriaBuilder = entityManager .getCriteriaBuilder ();
35
+ final CriteriaUpdate <Person > criteriaUpdate = criteriaBuilder .createCriteriaUpdate ( Person .class );
36
+ final Root <Person > root = criteriaUpdate .from ( Person .class );
37
+
38
+ final ParameterExpression <Integer > intValueParameter = criteriaBuilder .parameter ( Integer .class );
39
+ final ParameterExpression <String > stringValueParameter = criteriaBuilder .parameter ( String .class );
40
+
41
+ final EntityType <Person > personEntityType = entityManager .getMetamodel ().entity ( Person .class );
42
+
43
+ criteriaUpdate .set ( root .get ( personEntityType .getSingularAttribute ( "age" , Integer .class ) ),
44
+ intValueParameter );
45
+ criteriaUpdate .where (
46
+ criteriaBuilder .equal ( root .get ( personEntityType .getSingularAttribute ( "name" , String .class ) ),
47
+ stringValueParameter ) );
48
+
49
+ final Query query = entityManager .createQuery ( criteriaUpdate );
50
+ query .setParameter ( intValueParameter , 9 );
51
+ query .setParameter ( stringValueParameter , "Luigi" );
52
+
53
+ query .executeUpdate ();
54
+ } );
54
55
}
55
56
56
57
@ Test
57
58
public void testCriteriaUpdate2 (EntityManagerFactoryScope scope ) {
58
- scope .inTransaction (
59
- entityManager -> {
60
- final CriteriaBuilder criteriaBuilder = entityManager .getCriteriaBuilder ();
61
- final CriteriaUpdate <Person > criteriaUpdate = criteriaBuilder .createCriteriaUpdate ( Person .class );
62
- final Root <Person > root = criteriaUpdate .from ( Person .class );
59
+ scope .inTransaction ( entityManager -> {
60
+ final CriteriaBuilder criteriaBuilder = entityManager .getCriteriaBuilder ();
61
+ final CriteriaUpdate <Person > criteriaUpdate = criteriaBuilder .createCriteriaUpdate ( Person .class );
62
+ final Root <Person > root = criteriaUpdate .from ( Person .class );
63
63
64
- final ParameterExpression <Integer > intValueParameter = criteriaBuilder .parameter ( Integer .class );
65
- final ParameterExpression <String > stringValueParameter = criteriaBuilder .parameter ( String .class );
64
+ final ParameterExpression <Integer > intValueParameter = criteriaBuilder .parameter ( Integer .class );
65
+ final ParameterExpression <String > stringValueParameter = criteriaBuilder .parameter ( String .class );
66
66
67
- criteriaUpdate .set ( "age" , intValueParameter );
68
- criteriaUpdate .where ( criteriaBuilder .equal ( root .get ( "name" ), stringValueParameter ) );
67
+ criteriaUpdate .set ( "age" , intValueParameter );
68
+ criteriaUpdate .where ( criteriaBuilder .equal ( root .get ( "name" ), stringValueParameter ) );
69
69
70
- final Query query = entityManager .createQuery ( criteriaUpdate );
71
- query .setParameter ( intValueParameter , 9 );
72
- query .setParameter ( stringValueParameter , "Luigi" );
70
+ final Query query = entityManager .createQuery ( criteriaUpdate );
71
+ query .setParameter ( intValueParameter , 9 );
72
+ query .setParameter ( stringValueParameter , "Luigi" );
73
73
74
- query .executeUpdate ();
75
- }
76
- );
74
+ query .executeUpdate ();
75
+ } );
76
+ }
77
+
78
+ @ Test
79
+ public void testCriteriaUpdate3 (EntityManagerFactoryScope scope ) {
80
+ scope .inTransaction ( em -> {
81
+ // test separate value-bind parameters
82
+ final CriteriaBuilder cb = em .getCriteriaBuilder ();
83
+ final CriteriaUpdate <Process > cu = cb .createCriteriaUpdate ( Process .class );
84
+ final Root <Process > root = cu .from ( Process .class );
85
+ cu .set ( root .get ( "name" ), (Object ) null );
86
+ cu .set ( root .get ( "payload" ), (Object ) null );
87
+ em .createQuery ( cu ).executeUpdate ();
88
+ } );
89
+
90
+ scope .inTransaction ( em -> {
91
+ // test with the same cb.value( null ) parameter instance
92
+ final HibernateCriteriaBuilder cb = (HibernateCriteriaBuilder ) em .getCriteriaBuilder ();
93
+ final CriteriaUpdate <Process > cu = cb .createCriteriaUpdate ( Process .class );
94
+ final Root <Process > root = cu .from ( Process .class );
95
+ final Expression <Object > nullValue = cb .value ( null );
96
+ // a bit unfortunate, but we need to cast here to prevent ambiguous method references
97
+ final Path <String > name = root .get ( "name" );
98
+ final Path <byte []> payload = root .get ( "payload" );
99
+ final Expression <? extends String > nullString = cast ( nullValue );
100
+ final Expression <? extends byte []> nullBytes = cast ( nullValue );
101
+ cu .set ( name , nullString );
102
+ cu .set ( payload , nullBytes );
103
+ em .createQuery ( cu ).executeUpdate ();
104
+ } );
105
+ }
106
+
107
+ private static <X > Expression <? extends X > cast (Expression <?> expression ) {
108
+ //noinspection unchecked
109
+ return (Expression <? extends X >) expression ;
77
110
}
78
111
79
112
@ Entity (name = "Person" )
80
113
public static class Person {
81
-
82
114
@ Id
83
115
private String id ;
84
116
@@ -101,4 +133,18 @@ public Integer getAge() {
101
133
return age ;
102
134
}
103
135
}
136
+
137
+ @ Entity
138
+ public static class Process {
139
+ @ Id
140
+ @ GeneratedValue
141
+ private Long id ;
142
+
143
+ // All attributes below are necessary to reproduce the issue
144
+
145
+ private String name ;
146
+
147
+ @ Lob
148
+ private byte [] payload ;
149
+ }
104
150
}
0 commit comments