HHH-15458 Interpret String with JSON/XML type code as plain JSON/XML
This commit is contained in:
parent
33d2a7fc72
commit
eb1f56d542
|
@ -32,6 +32,7 @@ import jakarta.persistence.Table;
|
||||||
import static org.hamcrest.MatcherAssert.assertThat;
|
import static org.hamcrest.MatcherAssert.assertThat;
|
||||||
import static org.hamcrest.Matchers.equalTo;
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.isOneOf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Christian Beikov
|
* @author Christian Beikov
|
||||||
|
@ -73,23 +74,29 @@ public abstract class JsonMappingTests {
|
||||||
final BasicAttributeMapping payloadAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "payload" );
|
final BasicAttributeMapping payloadAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "payload" );
|
||||||
final BasicAttributeMapping objectMapAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "objectMap" );
|
final BasicAttributeMapping objectMapAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "objectMap" );
|
||||||
final BasicAttributeMapping listAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "list" );
|
final BasicAttributeMapping listAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "list" );
|
||||||
|
final BasicAttributeMapping jsonAttribute = (BasicAttributeMapping) entityDescriptor.findAttributeMapping( "jsonString" );
|
||||||
|
|
||||||
assertThat( payloadAttribute.getJavaType().getJavaTypeClass(), equalTo( Map.class ) );
|
assertThat( payloadAttribute.getJavaType().getJavaTypeClass(), equalTo( Map.class ) );
|
||||||
assertThat( objectMapAttribute.getJavaType().getJavaTypeClass(), equalTo( Map.class ) );
|
assertThat( objectMapAttribute.getJavaType().getJavaTypeClass(), equalTo( Map.class ) );
|
||||||
assertThat( listAttribute.getJavaType().getJavaTypeClass(), equalTo( List.class ) );
|
assertThat( listAttribute.getJavaType().getJavaTypeClass(), equalTo( List.class ) );
|
||||||
|
assertThat( jsonAttribute.getJavaType().getJavaTypeClass(), equalTo( String.class ) );
|
||||||
|
|
||||||
final JdbcType jsonType = jdbcTypeRegistry.getDescriptor( SqlTypes.JSON );
|
final JdbcType jsonType = jdbcTypeRegistry.getDescriptor( SqlTypes.JSON );
|
||||||
assertThat( payloadAttribute.getJdbcMapping().getJdbcType(), is( jsonType ) );
|
assertThat( payloadAttribute.getJdbcMapping().getJdbcType(), is( jsonType ) );
|
||||||
assertThat( objectMapAttribute.getJdbcMapping().getJdbcType(), is( jsonType ) );
|
assertThat( objectMapAttribute.getJdbcMapping().getJdbcType(), is( jsonType ) );
|
||||||
assertThat( listAttribute.getJdbcMapping().getJdbcType(), is( jsonType ) );
|
assertThat( listAttribute.getJdbcMapping().getJdbcType(), is( jsonType ) );
|
||||||
|
assertThat( jsonAttribute.getJdbcMapping().getJdbcType(), is( jsonType ) );
|
||||||
|
|
||||||
Map<String, String> stringMap = Map.of( "name", "ABC" );
|
Map<String, String> stringMap = Map.of( "name", "ABC" );
|
||||||
Map<StringNode, StringNode> objectMap = supportsObjectMapKey ? Map.of( new StringNode( "name" ), new StringNode( "ABC" ) ) : null;
|
Map<StringNode, StringNode> objectMap = supportsObjectMapKey ? Map.of( new StringNode( "name" ), new StringNode( "ABC" ) ) : null;
|
||||||
List<StringNode> list = List.of( new StringNode( "ABC" ) );
|
List<StringNode> list = List.of( new StringNode( "ABC" ) );
|
||||||
|
String json = "{\"name\":\"abc\"}";
|
||||||
|
// PostgreSQL returns the JSON slightly formatted
|
||||||
|
String alternativeJson = "{\"name\": \"abc\"}";
|
||||||
|
|
||||||
scope.inTransaction(
|
scope.inTransaction(
|
||||||
(session) -> {
|
(session) -> {
|
||||||
session.persist( new EntityWithJson( 1, stringMap, objectMap, list ) );
|
session.persist( new EntityWithJson( 1, stringMap, objectMap, list, json ) );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -99,6 +106,14 @@ public abstract class JsonMappingTests {
|
||||||
assertThat( entityWithJson.payload, is( stringMap ) );
|
assertThat( entityWithJson.payload, is( stringMap ) );
|
||||||
assertThat( entityWithJson.objectMap, is( objectMap ) );
|
assertThat( entityWithJson.objectMap, is( objectMap ) );
|
||||||
assertThat( entityWithJson.list, is( list ) );
|
assertThat( entityWithJson.list, is( list ) );
|
||||||
|
assertThat( entityWithJson.jsonString, isOneOf( json, alternativeJson ) );
|
||||||
|
String nativeJson = session.createNativeQuery(
|
||||||
|
"select jsonString from EntityWithJson",
|
||||||
|
String.class
|
||||||
|
)
|
||||||
|
.getResultList()
|
||||||
|
.get( 0 );
|
||||||
|
assertThat( nativeJson, isOneOf( json, alternativeJson ) );
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -120,6 +135,9 @@ public abstract class JsonMappingTests {
|
||||||
@JdbcTypeCode( SqlTypes.JSON )
|
@JdbcTypeCode( SqlTypes.JSON )
|
||||||
private List<StringNode> list;
|
private List<StringNode> list;
|
||||||
|
|
||||||
|
@JdbcTypeCode( SqlTypes.JSON )
|
||||||
|
private String jsonString;
|
||||||
|
|
||||||
public EntityWithJson() {
|
public EntityWithJson() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,11 +145,13 @@ public abstract class JsonMappingTests {
|
||||||
Integer id,
|
Integer id,
|
||||||
Map<String, String> payload,
|
Map<String, String> payload,
|
||||||
Map<StringNode, StringNode> objectMap,
|
Map<StringNode, StringNode> objectMap,
|
||||||
List<StringNode> list) {
|
List<StringNode> list,
|
||||||
|
String jsonString) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.payload = payload;
|
this.payload = payload;
|
||||||
this.objectMap = objectMap;
|
this.objectMap = objectMap;
|
||||||
this.list = list;
|
this.list = list;
|
||||||
|
this.jsonString = jsonString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,9 @@ public final class JacksonJsonFormatMapper implements FormatMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
||||||
|
if ( javaType.getJavaType() == String.class ) {
|
||||||
|
return (T) charSequence.toString();
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue( charSequence.toString(), objectMapper.constructType( javaType.getJavaType() ) );
|
return objectMapper.readValue( charSequence.toString(), objectMapper.constructType( javaType.getJavaType() ) );
|
||||||
}
|
}
|
||||||
|
@ -42,6 +45,9 @@ public final class JacksonJsonFormatMapper implements FormatMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
||||||
|
if ( javaType.getJavaType() == String.class ) {
|
||||||
|
return (String) value;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.writerFor( objectMapper.constructType( javaType.getJavaType() ) )
|
return objectMapper.writerFor( objectMapper.constructType( javaType.getJavaType() ) )
|
||||||
.writeValueAsString( value );
|
.writeValueAsString( value );
|
||||||
|
|
|
@ -33,6 +33,9 @@ public final class JacksonXmlFormatMapper implements FormatMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
||||||
|
if ( javaType.getJavaType() == String.class ) {
|
||||||
|
return (T) charSequence.toString();
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue( charSequence.toString(), objectMapper.constructType( javaType.getJavaType() ) );
|
return objectMapper.readValue( charSequence.toString(), objectMapper.constructType( javaType.getJavaType() ) );
|
||||||
}
|
}
|
||||||
|
@ -43,6 +46,9 @@ public final class JacksonXmlFormatMapper implements FormatMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
||||||
|
if ( javaType.getJavaType() == String.class ) {
|
||||||
|
return (String) value;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return objectMapper.writerFor( objectMapper.constructType( javaType.getJavaType() ) )
|
return objectMapper.writerFor( objectMapper.constructType( javaType.getJavaType() ) )
|
||||||
.writeValueAsString( value );
|
.writeValueAsString( value );
|
||||||
|
|
|
@ -33,6 +33,9 @@ public final class JsonBJsonFormatMapper implements FormatMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
||||||
|
if ( javaType.getJavaType() == String.class ) {
|
||||||
|
return (T) charSequence.toString();
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return jsonb.fromJson( charSequence.toString(), javaType.getJavaType() );
|
return jsonb.fromJson( charSequence.toString(), javaType.getJavaType() );
|
||||||
}
|
}
|
||||||
|
@ -43,6 +46,9 @@ public final class JsonBJsonFormatMapper implements FormatMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
||||||
|
if ( javaType.getJavaType() == String.class ) {
|
||||||
|
return (String) value;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return jsonb.toJson( value, javaType.getJavaType() );
|
return jsonb.toJson( value, javaType.getJavaType() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,9 @@ public final class JaxbXmlFormatMapper implements FormatMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
public <T> T fromString(CharSequence charSequence, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
||||||
|
if ( javaType.getJavaType() == String.class ) {
|
||||||
|
return (T) charSequence.toString();
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
if ( Map.class.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
|
if ( Map.class.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
|
||||||
final JAXBContext context;
|
final JAXBContext context;
|
||||||
|
@ -191,6 +194,9 @@ public final class JaxbXmlFormatMapper implements FormatMapper {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
public <T> String toString(T value, JavaType<T> javaType, WrapperOptions wrapperOptions) {
|
||||||
|
if ( javaType.getJavaType() == String.class ) {
|
||||||
|
return (String) value;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
final StringWriter stringWriter = new StringWriter();
|
final StringWriter stringWriter = new StringWriter();
|
||||||
if ( Map.class.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
|
if ( Map.class.isAssignableFrom( javaType.getJavaTypeClass() ) ) {
|
||||||
|
|
Loading…
Reference in New Issue