Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,9 @@ public <Y> SqmUpdateStatement<T> set(SingularAttribute<? super T, Y> attribute,

@Override
public <Y, X extends Y> SqmUpdateStatement<T> set(Path<Y> attribute, X value) {
applyAssignment( (SqmPath<Y>) attribute, (SqmExpression<? extends Y>) nodeBuilder().value( value ) );
final SqmCriteriaNodeBuilder nodeBuilder = (SqmCriteriaNodeBuilder) nodeBuilder();
final SqmPath<Y> sqmAttribute = (SqmPath<Y>) attribute;
applyAssignment( sqmAttribute, nodeBuilder.value( value, sqmAttribute ) );
return this;
}

Expand All @@ -192,15 +194,15 @@ public <Y> SqmUpdateStatement<T> set(Path<Y> attribute, Expression<? extends Y>

@Override @SuppressWarnings({"rawtypes", "unchecked"})
public SqmUpdateStatement<T> set(String attributeName, Object value) {
final SqmPath sqmPath = getTarget().get(attributeName);
final SqmPath sqmPath = getTarget().get( attributeName );
final SqmExpression expression;
if ( value instanceof SqmExpression ) {
expression = (SqmExpression) value;
}
else {
expression = (SqmExpression) nodeBuilder().value( value );
final SqmCriteriaNodeBuilder nodeBuilder = (SqmCriteriaNodeBuilder) nodeBuilder();
expression = nodeBuilder.value( value, sqmPath );
}
assertAssignable( null, sqmPath, expression, nodeBuilder() );
applyAssignment( sqmPath, expression );
return this;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,51 @@
*/
package org.hibernate.orm.test.mapping.basic;

import java.nio.charset.StandardCharsets;
import java.sql.Blob;
import java.sql.Clob;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.databind.JsonNode;
import jakarta.json.JsonValue;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import jakarta.persistence.criteria.CriteriaUpdate;
import jakarta.persistence.criteria.Root;
import org.hibernate.annotations.JdbcTypeCode;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.community.dialect.AltibaseDialect;
import org.hibernate.dialect.HANADialect;
import org.hibernate.community.dialect.DerbyDialect;
import org.hibernate.dialect.HANADialect;
import org.hibernate.dialect.OracleDialect;
import org.hibernate.dialect.SybaseDialect;
import org.hibernate.metamodel.mapping.internal.BasicAttributeMapping;
import org.hibernate.metamodel.spi.MappingMetamodelImplementor;
import org.hibernate.persister.entity.EntityPersister;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;

import org.hibernate.query.MutationQuery;
import org.hibernate.query.criteria.HibernateCriteriaBuilder;
import org.hibernate.testing.orm.junit.DomainModel;
import org.hibernate.testing.orm.junit.Jira;
import org.hibernate.testing.orm.junit.JiraKey;
import org.hibernate.testing.orm.junit.ServiceRegistry;
import org.hibernate.testing.orm.junit.SessionFactory;
import org.hibernate.testing.orm.junit.SessionFactoryScope;
import org.hibernate.testing.orm.junit.Setting;
import org.hibernate.testing.orm.junit.SkipForDialect;
import org.hibernate.type.SqlTypes;
import org.hibernate.type.descriptor.jdbc.JdbcType;
import org.hibernate.type.descriptor.jdbc.spi.JdbcTypeRegistry;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.nio.charset.StandardCharsets;
import java.sql.Blob;
import java.sql.Clob;
import java.util.List;
import java.util.Map;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.isOneOf;
import static org.hamcrest.Matchers.isA;
import static org.hamcrest.Matchers.isOneOf;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;

Expand Down Expand Up @@ -120,7 +123,8 @@ public void verifyMappings(SessionFactoryScope scope) {
"objectMap" );
final BasicAttributeMapping listAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping(
"list" );
final BasicAttributeMapping jsonAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "jsonString" );
final BasicAttributeMapping jsonAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping(
"jsonString" );

assertThat( stringMapAttribute.getJavaType().getJavaTypeClass(), equalTo( Map.class ) );
assertThat( objectMapAttribute.getJavaType().getJavaTypeClass(), equalTo( Map.class ) );
Expand All @@ -142,8 +146,8 @@ public void verifyReadWorks(SessionFactoryScope scope) {
assertThat( entityWithJson.stringMap, is( stringMap ) );
assertThat( entityWithJson.objectMap, is( objectMap ) );
assertThat( entityWithJson.list, is( list ) );
assertThat( entityWithJson.jsonNode, is( nullValue() ));
assertThat( entityWithJson.jsonValue, is( nullValue() ));
assertThat( entityWithJson.jsonNode, is( nullValue() ) );
assertThat( entityWithJson.jsonValue, is( nullValue() ) );
}
);
}
Expand All @@ -163,14 +167,14 @@ public void verifyMergeWorks(SessionFactoryScope scope) {
assertThat( entityWithJson.objectMap, is( nullValue() ) );
assertThat( entityWithJson.list, is( nullValue() ) );
assertThat( entityWithJson.jsonString, is( nullValue() ) );
assertThat( entityWithJson.jsonNode, is( nullValue() ));
assertThat( entityWithJson.jsonValue, is( nullValue() ));
assertThat( entityWithJson.jsonNode, is( nullValue() ) );
assertThat( entityWithJson.jsonValue, is( nullValue() ) );
}
);
}

@Test
@JiraKey( "HHH-16682" )
@JiraKey("HHH-16682")
public void verifyDirtyChecking(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
Expand All @@ -187,14 +191,19 @@ public void verifyDirtyChecking(SessionFactoryScope scope) {
}

@Test
@SkipForDialect(dialectClass = DerbyDialect.class, reason = "Derby doesn't support comparing CLOBs with the = operator")
@SkipForDialect(dialectClass = HANADialect.class, matchSubTypes = true, reason = "HANA doesn't support comparing LOBs with the = operator")
@SkipForDialect(dialectClass = SybaseDialect.class, matchSubTypes = true, reason = "Sybase doesn't support comparing LOBs with the = operator")
@SkipForDialect(dialectClass = OracleDialect.class, matchSubTypes = true, reason = "Oracle doesn't support comparing JSON with the = operator")
@SkipForDialect(dialectClass = AltibaseDialect.class, reason = "Altibase doesn't support comparing CLOBs with the = operator")
@SkipForDialect(dialectClass = DerbyDialect.class,
reason = "Derby doesn't support comparing CLOBs with the = operator")
@SkipForDialect(dialectClass = HANADialect.class, matchSubTypes = true,
reason = "HANA doesn't support comparing LOBs with the = operator")
@SkipForDialect(dialectClass = SybaseDialect.class, matchSubTypes = true,
reason = "Sybase doesn't support comparing LOBs with the = operator")
@SkipForDialect(dialectClass = OracleDialect.class, matchSubTypes = true,
reason = "Oracle doesn't support comparing JSON with the = operator")
@SkipForDialect(dialectClass = AltibaseDialect.class,
reason = "Altibase doesn't support comparing CLOBs with the = operator")
public void verifyComparisonWorks(SessionFactoryScope scope) {
scope.inTransaction(
(session) -> {
(session) -> {
// PostgreSQL returns the JSON slightly formatted
String alternativeJson = "{\"name\": \"abc\"}";
EntityWithJson entityWithJson = session.createQuery(
Expand Down Expand Up @@ -239,6 +248,32 @@ else if ( nativeJson instanceof Clob ) {
);
}

@Test
@Jira("https://hibernate.atlassian.net/browse/HHH-18709")
public void verifyCriteriaUpdateQueryWorks(SessionFactoryScope scope) {
final Map<String, String> newMap = Map.of( "name", "ABC" );
final List<StringNode> newList = List.of( new StringNode( "ABC" ) );
final String newJson = "{\"count\":123}";
scope.inTransaction( session -> {
final HibernateCriteriaBuilder builder = session.getCriteriaBuilder();
final CriteriaUpdate<EntityWithJson> criteria = builder.createCriteriaUpdate( EntityWithJson.class );
final Root<EntityWithJson> root = criteria.from( EntityWithJson.class );
criteria.set( root.get( "stringMap" ), newMap );
criteria.set( "list", newList );
criteria.set( root.get( "jsonString" ), newJson );
criteria.where( builder.equal( root.get( "id" ), 1 ) );
final MutationQuery query = session.createMutationQuery( criteria );
final int count = query.executeUpdate();
assertThat( count, is( 1 ) );
} );
scope.inSession( session -> {
final EntityWithJson entityWithJson = session.find( EntityWithJson.class, 1 );
assertThat( entityWithJson.stringMap, is( newMap ) );
assertThat( entityWithJson.list, is( newList ) );
assertThat( entityWithJson.jsonString.replaceAll( "\\s", "" ), is( newJson ) );
} );
}

@Entity(name = "EntityWithJson")
@Table(name = "EntityWithJson")
public static class EntityWithJson {
Expand Down