Skip to content

Commit bc77876

Browse files
yrodierembellade
authored andcommitted
HHH-19750 Add test for issue
1 parent 1781736 commit bc77876

File tree

1 file changed

+96
-50
lines changed

1 file changed

+96
-50
lines changed

hibernate-core/src/test/java/org/hibernate/orm/test/jpa/query/CriteriaUpdateWithParametersTest.java

Lines changed: 96 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -4,81 +4,113 @@
44
*/
55
package org.hibernate.orm.test.jpa.query;
66

7-
import org.hibernate.testing.orm.junit.EntityManagerFactoryScope;
8-
import org.hibernate.testing.orm.junit.Jpa;
9-
import org.junit.jupiter.api.Test;
10-
117
import jakarta.persistence.Entity;
8+
import jakarta.persistence.GeneratedValue;
129
import jakarta.persistence.Id;
10+
import jakarta.persistence.Lob;
1311
import jakarta.persistence.Query;
1412
import jakarta.persistence.criteria.CriteriaBuilder;
1513
import jakarta.persistence.criteria.CriteriaUpdate;
14+
import jakarta.persistence.criteria.Expression;
1615
import jakarta.persistence.criteria.ParameterExpression;
16+
import jakarta.persistence.criteria.Path;
1717
import jakarta.persistence.criteria.Root;
1818
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;
1923

20-
@Jpa(
21-
annotatedClasses = CriteriaUpdateWithParametersTest.Person.class
22-
)
24+
25+
@Jpa(annotatedClasses = {
26+
CriteriaUpdateWithParametersTest.Person.class,
27+
CriteriaUpdateWithParametersTest.Process.class
28+
})
2329
public class CriteriaUpdateWithParametersTest {
2430

2531
@Test
2632
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+
} );
5455
}
5556

5657
@Test
5758
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 );
6363

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 );
6666

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 ) );
6969

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" );
7373

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;
77110
}
78111

79112
@Entity(name = "Person")
80113
public static class Person {
81-
82114
@Id
83115
private String id;
84116

@@ -101,4 +133,18 @@ public Integer getAge() {
101133
return age;
102134
}
103135
}
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+
}
104150
}

0 commit comments

Comments
 (0)