44 */
55package org .hibernate .orm .test .mapping .basic ;
66
7- import java .nio .charset .StandardCharsets ;
8- import java .sql .Blob ;
9- import java .sql .Clob ;
10- import java .util .List ;
11- import java .util .Map ;
12-
137import com .fasterxml .jackson .databind .JsonNode ;
148import jakarta .json .JsonValue ;
9+ import jakarta .persistence .Entity ;
10+ import jakarta .persistence .Id ;
11+ import jakarta .persistence .Table ;
12+ import jakarta .persistence .criteria .CriteriaUpdate ;
13+ import jakarta .persistence .criteria .Root ;
1514import org .hibernate .annotations .JdbcTypeCode ;
1615import org .hibernate .cfg .AvailableSettings ;
1716import org .hibernate .community .dialect .AltibaseDialect ;
18- import org .hibernate .dialect .HANADialect ;
1917import org .hibernate .community .dialect .DerbyDialect ;
18+ import org .hibernate .dialect .HANADialect ;
2019import org .hibernate .dialect .OracleDialect ;
2120import org .hibernate .dialect .SybaseDialect ;
2221import org .hibernate .metamodel .mapping .internal .BasicAttributeMapping ;
2322import org .hibernate .metamodel .spi .MappingMetamodelImplementor ;
2423import org .hibernate .persister .entity .EntityPersister ;
25- import org .hibernate .type .SqlTypes ;
26- import org .hibernate .type .descriptor .jdbc .JdbcType ;
27- import org .hibernate .type .descriptor .jdbc .spi .JdbcTypeRegistry ;
28-
24+ import org .hibernate .query .MutationQuery ;
25+ import org .hibernate .query .criteria .HibernateCriteriaBuilder ;
2926import org .hibernate .testing .orm .junit .DomainModel ;
27+ import org .hibernate .testing .orm .junit .Jira ;
3028import org .hibernate .testing .orm .junit .JiraKey ;
3129import org .hibernate .testing .orm .junit .ServiceRegistry ;
3230import org .hibernate .testing .orm .junit .SessionFactory ;
3331import org .hibernate .testing .orm .junit .SessionFactoryScope ;
3432import org .hibernate .testing .orm .junit .Setting ;
3533import org .hibernate .testing .orm .junit .SkipForDialect ;
34+ import org .hibernate .type .SqlTypes ;
35+ import org .hibernate .type .descriptor .jdbc .JdbcType ;
36+ import org .hibernate .type .descriptor .jdbc .spi .JdbcTypeRegistry ;
3637import org .junit .jupiter .api .AfterEach ;
3738import org .junit .jupiter .api .BeforeEach ;
3839import org .junit .jupiter .api .Test ;
3940
40- import jakarta .persistence .Entity ;
41- import jakarta .persistence .Id ;
42- import jakarta .persistence .Table ;
41+ import java .nio .charset .StandardCharsets ;
42+ import java .sql .Blob ;
43+ import java .sql .Clob ;
44+ import java .util .List ;
45+ import java .util .Map ;
4346
4447import static org .hamcrest .MatcherAssert .assertThat ;
4548import static org .hamcrest .Matchers .equalTo ;
4649import static org .hamcrest .Matchers .is ;
47- import static org .hamcrest .Matchers .isOneOf ;
4850import static org .hamcrest .Matchers .isA ;
51+ import static org .hamcrest .Matchers .isOneOf ;
4952import static org .hamcrest .Matchers .notNullValue ;
5053import static org .hamcrest .Matchers .nullValue ;
5154
@@ -120,7 +123,8 @@ public void verifyMappings(SessionFactoryScope scope) {
120123 "objectMap" );
121124 final BasicAttributeMapping listAttribute = (BasicAttributeMapping ) entityDescriptor .findAttributeMapping (
122125 "list" );
123- final BasicAttributeMapping jsonAttribute = (BasicAttributeMapping ) entityDescriptor .findAttributeMapping ( "jsonString" );
126+ final BasicAttributeMapping jsonAttribute = (BasicAttributeMapping ) entityDescriptor .findAttributeMapping (
127+ "jsonString" );
124128
125129 assertThat ( stringMapAttribute .getJavaType ().getJavaTypeClass (), equalTo ( Map .class ) );
126130 assertThat ( objectMapAttribute .getJavaType ().getJavaTypeClass (), equalTo ( Map .class ) );
@@ -142,8 +146,8 @@ public void verifyReadWorks(SessionFactoryScope scope) {
142146 assertThat ( entityWithJson .stringMap , is ( stringMap ) );
143147 assertThat ( entityWithJson .objectMap , is ( objectMap ) );
144148 assertThat ( entityWithJson .list , is ( list ) );
145- assertThat ( entityWithJson .jsonNode , is ( nullValue () ));
146- assertThat ( entityWithJson .jsonValue , is ( nullValue () ));
149+ assertThat ( entityWithJson .jsonNode , is ( nullValue () ) );
150+ assertThat ( entityWithJson .jsonValue , is ( nullValue () ) );
147151 }
148152 );
149153 }
@@ -163,14 +167,14 @@ public void verifyMergeWorks(SessionFactoryScope scope) {
163167 assertThat ( entityWithJson .objectMap , is ( nullValue () ) );
164168 assertThat ( entityWithJson .list , is ( nullValue () ) );
165169 assertThat ( entityWithJson .jsonString , is ( nullValue () ) );
166- assertThat ( entityWithJson .jsonNode , is ( nullValue () ));
167- assertThat ( entityWithJson .jsonValue , is ( nullValue () ));
170+ assertThat ( entityWithJson .jsonNode , is ( nullValue () ) );
171+ assertThat ( entityWithJson .jsonValue , is ( nullValue () ) );
168172 }
169173 );
170174 }
171175
172176 @ Test
173- @ JiraKey ( "HHH-16682" )
177+ @ JiraKey ("HHH-16682" )
174178 public void verifyDirtyChecking (SessionFactoryScope scope ) {
175179 scope .inTransaction (
176180 (session ) -> {
@@ -187,14 +191,19 @@ public void verifyDirtyChecking(SessionFactoryScope scope) {
187191 }
188192
189193 @ Test
190- @ SkipForDialect (dialectClass = DerbyDialect .class , reason = "Derby doesn't support comparing CLOBs with the = operator" )
191- @ SkipForDialect (dialectClass = HANADialect .class , matchSubTypes = true , reason = "HANA doesn't support comparing LOBs with the = operator" )
192- @ SkipForDialect (dialectClass = SybaseDialect .class , matchSubTypes = true , reason = "Sybase doesn't support comparing LOBs with the = operator" )
193- @ SkipForDialect (dialectClass = OracleDialect .class , matchSubTypes = true , reason = "Oracle doesn't support comparing JSON with the = operator" )
194- @ SkipForDialect (dialectClass = AltibaseDialect .class , reason = "Altibase doesn't support comparing CLOBs with the = operator" )
194+ @ SkipForDialect (dialectClass = DerbyDialect .class ,
195+ reason = "Derby doesn't support comparing CLOBs with the = operator" )
196+ @ SkipForDialect (dialectClass = HANADialect .class , matchSubTypes = true ,
197+ reason = "HANA doesn't support comparing LOBs with the = operator" )
198+ @ SkipForDialect (dialectClass = SybaseDialect .class , matchSubTypes = true ,
199+ reason = "Sybase doesn't support comparing LOBs with the = operator" )
200+ @ SkipForDialect (dialectClass = OracleDialect .class , matchSubTypes = true ,
201+ reason = "Oracle doesn't support comparing JSON with the = operator" )
202+ @ SkipForDialect (dialectClass = AltibaseDialect .class ,
203+ reason = "Altibase doesn't support comparing CLOBs with the = operator" )
195204 public void verifyComparisonWorks (SessionFactoryScope scope ) {
196205 scope .inTransaction (
197- (session ) -> {
206+ (session ) -> {
198207 // PostgreSQL returns the JSON slightly formatted
199208 String alternativeJson = "{\" name\" : \" abc\" }" ;
200209 EntityWithJson entityWithJson = session .createQuery (
@@ -239,6 +248,32 @@ else if ( nativeJson instanceof Clob ) {
239248 );
240249 }
241250
251+ @ Test
252+ @ Jira ( "https://hibernate.atlassian.net/browse/HHH-18709" )
253+ public void verifyCriteriaUpdateQueryWorks (SessionFactoryScope scope ) {
254+ final Map <String , String > newMap = Map .of ( "name" , "ABC" );
255+ final List <StringNode > newList = List .of ( new StringNode ( "ABC" ) );
256+ final String newJson = "{\" count\" : 123}" ;
257+ scope .inTransaction ( session -> {
258+ final HibernateCriteriaBuilder builder = session .getCriteriaBuilder ();
259+ final CriteriaUpdate <EntityWithJson > criteria = builder .createCriteriaUpdate ( EntityWithJson .class );
260+ final Root <EntityWithJson > root = criteria .from ( EntityWithJson .class );
261+ criteria .set ( root .get ( "stringMap" ), newMap );
262+ criteria .set ( root .get ( "list" ), newList );
263+ criteria .set ( root .get ( "jsonString" ), newJson );
264+ criteria .where ( builder .equal ( root .get ( "id" ), 1 ) );
265+ final MutationQuery query = session .createMutationQuery ( criteria );
266+ final int count = query .executeUpdate ();
267+ assertThat ( count , is ( 1 ) );
268+ } );
269+ scope .inSession ( session -> {
270+ final EntityWithJson entityWithJson = session .find ( EntityWithJson .class , 1 );
271+ assertThat ( entityWithJson .stringMap , is ( newMap ) );
272+ assertThat ( entityWithJson .list , is ( newList ) );
273+ assertThat ( entityWithJson .jsonString , is ( newJson ) );
274+ } );
275+ }
276+
242277 @ Entity (name = "EntityWithJson" )
243278 @ Table (name = "EntityWithJson" )
244279 public static class EntityWithJson {
0 commit comments