Skip to content

Commit 7046f95

Browse files
committed
HHH-17404 Cleanup JsonHelper and fix nested parsing
1 parent 7e6e831 commit 7046f95

File tree

8 files changed

+506
-454
lines changed

8 files changed

+506
-454
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/JsonHelper.java

Lines changed: 217 additions & 325 deletions
Large diffs are not rendered by default.

hibernate-core/src/main/java/org/hibernate/dialect/OracleOsonJacksonArrayJdbcType.java

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,12 @@
44
*/
55
package org.hibernate.dialect;
66

7-
import com.fasterxml.jackson.core.JsonFactory;
87
import com.fasterxml.jackson.core.JsonParser;
98
import oracle.jdbc.OracleType;
109
import oracle.jdbc.driver.DatabaseError;
11-
import oracle.jdbc.provider.oson.OsonFactory;
1210
import oracle.sql.json.OracleJsonDatum;
13-
import oracle.sql.json.OracleJsonFactory;
1411
import oracle.sql.json.OracleJsonGenerator;
1512

16-
import oracle.sql.json.OracleJsonParser;
1713
import org.hibernate.internal.CoreLogging;
1814
import org.hibernate.internal.CoreMessageLogger;
1915
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
@@ -22,12 +18,12 @@
2218
import org.hibernate.type.descriptor.WrapperOptions;
2319
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
2420
import org.hibernate.type.descriptor.java.JavaType;
21+
import org.hibernate.type.descriptor.java.spi.UnknownBasicJavaType;
2522
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
2623
import org.hibernate.type.descriptor.jdbc.BasicBinder;
2724
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
2825
import org.hibernate.type.descriptor.jdbc.JdbcType;
2926
import org.hibernate.type.descriptor.jdbc.JsonJdbcType;
30-
import org.hibernate.type.format.FormatMapper;
3127
import org.hibernate.type.format.OsonDocumentReader;
3228
import org.hibernate.type.format.OsonDocumentWriter;
3329

@@ -39,6 +35,9 @@
3935
import java.sql.ResultSet;
4036
import java.sql.SQLException;
4137

38+
import static org.hibernate.dialect.OracleOsonJacksonJdbcType.OSON_JACKSON_FACTORY;
39+
import static org.hibernate.dialect.OracleOsonJacksonJdbcType.OSON_JSON_FACTORY;
40+
4241
/**
4342
*
4443
* Type mapping of (JSON) array of JSON SQL data type for Oracle database.
@@ -52,8 +51,6 @@ public class OracleOsonJacksonArrayJdbcType extends OracleJsonArrayJdbcType {
5251

5352
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( OracleOsonJacksonArrayJdbcType.class );
5453

55-
private static final OsonFactory osonFactory = new OsonFactory();
56-
5754
public OracleOsonJacksonArrayJdbcType(JdbcType elementJdbcType) {
5855
super(elementJdbcType);
5956
}
@@ -70,29 +67,31 @@ public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
7067

7168
return new BasicBinder<>( javaType, this ) {
7269

73-
private <X> byte[] toOsonStream(X value, JavaType<X> javaType, WrapperOptions options) throws Exception {
70+
private <T> byte[] toOsonStream(T value, JavaType<T> javaType, WrapperOptions options) throws Exception {
7471
final Object[] domainObjects = javaType.unwrap( value, Object[].class, options );
75-
76-
ByteArrayOutputStream out = new ByteArrayOutputStream();
77-
try (OracleJsonGenerator generator = new OracleJsonFactory().createJsonBinaryGenerator( out )) {
78-
OsonDocumentWriter writer = new OsonDocumentWriter( generator );
79-
80-
if ( getElementJdbcType() instanceof JsonJdbcType jsonElementJdbcType ) {
81-
final EmbeddableMappingType embeddableMappingType = jsonElementJdbcType.getEmbeddableMappingType();
82-
JsonHelper.serializeArray( embeddableMappingType, domainObjects, options, writer );
72+
final ByteArrayOutputStream out = new ByteArrayOutputStream();
73+
try (OracleJsonGenerator generator = OSON_JSON_FACTORY.createJsonBinaryGenerator( out )) {
74+
final JavaType<?> elementJavaType = ((BasicPluralJavaType<?>) javaType).getElementJavaType();
75+
if ( elementJavaType instanceof UnknownBasicJavaType<?> ) {
76+
options.getJsonFormatMapper().writeToTarget( value, javaType, generator, options);
8377
}
8478
else {
85-
assert !( getElementJdbcType() instanceof AggregateJdbcType );
86-
final JavaType<?> elementJavaType = ( (BasicPluralJavaType<?>) javaType ).getElementJavaType();
87-
JsonHelper.serializeArray(
88-
elementJavaType,
89-
getElementJdbcType(),
90-
domainObjects,
91-
options,
92-
writer
93-
);
79+
final OsonDocumentWriter writer = new OsonDocumentWriter( generator );
80+
if ( getElementJdbcType() instanceof JsonJdbcType jsonElementJdbcType ) {
81+
final EmbeddableMappingType embeddableMappingType = jsonElementJdbcType.getEmbeddableMappingType();
82+
JsonHelper.serializeArray( embeddableMappingType, domainObjects, options, writer );
83+
}
84+
else {
85+
assert !(getElementJdbcType() instanceof AggregateJdbcType);
86+
JsonHelper.serializeArray(
87+
elementJavaType,
88+
getElementJdbcType(),
89+
domainObjects,
90+
options,
91+
writer
92+
);
93+
}
9494
}
95-
generator.close();
9695
return out.toByteArray();
9796
}
9897

@@ -127,20 +126,20 @@ public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
127126
return new BasicExtractor<>( javaType, this ) {
128127

129128
private X fromOson(InputStream osonBytes, WrapperOptions options) throws Exception {
130-
FormatMapper mapper = options.getJsonFormatMapper();
131-
OracleJsonParser osonParser = new OracleJsonFactory().createJsonBinaryParser( osonBytes );
132-
final JdbcType elementJdbcType = getElementJdbcType();
133-
if (elementJdbcType instanceof JsonJdbcType) {
134-
if (((JsonJdbcType) elementJdbcType).getEmbeddableMappingType() != null) {
135-
// embeddable array case.
136-
return JsonHelper.deserializeArray( javaType,
137-
elementJdbcType, new OsonDocumentReader( osonParser ), options );
129+
if ( ((BasicPluralJavaType<?>) getJavaType()).getElementJavaType() instanceof UnknownBasicJavaType<?> ) {
130+
try (JsonParser oParser = OSON_JACKSON_FACTORY.createParser( osonBytes )) {
131+
return options.getJsonFormatMapper().readFromSource( getJavaType(), oParser, options );
138132
}
139133
}
140-
try (JsonParser oParser = ((JsonFactory)osonFactory).createParser( osonBytes )) {
141-
return mapper.readFromSource( getJavaType(), oParser, options);
134+
else {
135+
// embeddable array case.
136+
return JsonHelper.deserializeArray(
137+
javaType,
138+
getElementJdbcType(),
139+
new OsonDocumentReader( OSON_JSON_FACTORY.createJsonBinaryParser( osonBytes ) ),
140+
options
141+
);
142142
}
143-
144143
}
145144

146145
private X doExtraction(OracleJsonDatum datum, WrapperOptions options) throws SQLException {

hibernate-core/src/main/java/org/hibernate/dialect/OracleOsonJacksonJdbcType.java

Lines changed: 22 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
*/
55
package org.hibernate.dialect;
66

7-
import com.fasterxml.jackson.core.JsonFactory;
87
import com.fasterxml.jackson.core.JsonGenerator;
98
import com.fasterxml.jackson.core.JsonParser;
109
import oracle.jdbc.OracleType;
@@ -13,7 +12,6 @@
1312
import oracle.sql.json.OracleJsonDatum;
1413
import oracle.sql.json.OracleJsonFactory;
1514
import oracle.sql.json.OracleJsonGenerator;
16-
import oracle.sql.json.OracleJsonParser;
1715
import org.hibernate.internal.CoreLogging;
1816
import org.hibernate.internal.CoreMessageLogger;
1917
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
@@ -25,7 +23,6 @@
2523
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
2624
import org.hibernate.type.descriptor.jdbc.BasicBinder;
2725
import org.hibernate.type.descriptor.jdbc.BasicExtractor;
28-
import org.hibernate.type.format.FormatMapper;
2926
import org.hibernate.type.format.OsonDocumentReader;
3027
import org.hibernate.type.format.OsonDocumentWriter;
3128

@@ -50,7 +47,8 @@ public class OracleOsonJacksonJdbcType extends OracleJsonJdbcType {
5047

5148
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( OracleOsonJacksonJdbcType.class );
5249

53-
private static final OsonFactory osonFactory = new OsonFactory();
50+
static final OsonFactory OSON_JACKSON_FACTORY = new OsonFactory();
51+
static final OracleJsonFactory OSON_JSON_FACTORY = new OracleJsonFactory();
5452

5553
private OracleOsonJacksonJdbcType(EmbeddableMappingType embeddableMappingType) {
5654
super( embeddableMappingType );
@@ -78,23 +76,23 @@ public <X> ValueBinder<X> getBinder(JavaType<X> javaType) {
7876

7977
return new BasicBinder<>( javaType, this ) {
8078

81-
private <X> byte[] toOson(X value, JavaType<X> javaType, WrapperOptions options) throws Exception {
82-
83-
FormatMapper mapper = options.getJsonFormatMapper();
84-
79+
private <T> byte[] toOson(T value, JavaType<T> javaType, WrapperOptions options) throws Exception {
80+
final ByteArrayOutputStream out = new ByteArrayOutputStream();
8581
if (getEmbeddableMappingType() != null) {
86-
ByteArrayOutputStream out = new ByteArrayOutputStream();
8782
// OracleJsonFactory is used and not OracleOsonFactory as Jackson is not involved here
88-
try (OracleJsonGenerator generator = new OracleJsonFactory().createJsonBinaryGenerator( out )) {
89-
OsonDocumentWriter writer = new OsonDocumentWriter( generator);
90-
JsonHelper.serialize( getEmbeddableMappingType(), value,options,writer);
83+
try (OracleJsonGenerator generator = OSON_JSON_FACTORY.createJsonBinaryGenerator( out )) {
84+
JsonHelper.serialize(
85+
getEmbeddableMappingType(),
86+
value,
87+
options,
88+
new OsonDocumentWriter( generator )
89+
);
9190
}
92-
return out.toByteArray();
9391
}
94-
95-
ByteArrayOutputStream out = new ByteArrayOutputStream();
96-
try (JsonGenerator osonGen = osonFactory.createGenerator( out )) {
97-
mapper.writeToTarget( value, javaType, osonGen, options );
92+
else {
93+
try (JsonGenerator osonGen = OSON_JACKSON_FACTORY.createGenerator( out )) {
94+
options.getJsonFormatMapper().writeToTarget( value, javaType, osonGen, options );
95+
}
9896
}
9997
return out.toByteArray();
10098
}
@@ -133,33 +131,18 @@ public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
133131
return new BasicExtractor<>( javaType, this ) {
134132

135133
private X fromOson(InputStream osonBytes, WrapperOptions options) throws Exception {
136-
137-
FormatMapper mapper = options.getJsonFormatMapper();
138-
139-
if (getEmbeddableMappingType() != null &&
140-
getJavaType().getJavaTypeClass() == Object[].class) {
141-
// We are dealing with embeddable (@Embeddable) and we request
142-
// an array of objects. We use JsonParser to fetch values
143-
// and build the array.(as opposed to let Jackson do it as we do not
144-
// have a proper object definition at that stage).
145-
OracleJsonParser osonParser = new OracleJsonFactory().createJsonBinaryParser( osonBytes );
146-
Object[] objects = JsonHelper.deserialize(
134+
if ( getEmbeddableMappingType() != null ) {
135+
return JsonHelper.deserialize(
147136
getEmbeddableMappingType(),
148-
new OsonDocumentReader(osonParser),
137+
new OsonDocumentReader( OSON_JSON_FACTORY.createJsonBinaryParser( osonBytes ) ),
149138
javaType.getJavaTypeClass() != Object[].class,
150139
options
151140
);
152-
return (X) objects;
153141
}
154-
155-
JavaType <X> type = getJavaType();
156-
if (getEmbeddableMappingType() != null) {
157-
// We are dealing with embeddable (@Embeddable)
158-
type = (JavaType<X>) getEmbeddableMappingType().getJavaType();
159-
}
160-
161-
try (JsonParser osonParser = ((JsonFactory)osonFactory).createParser( osonBytes )) {
162-
return mapper.readFromSource( type, osonParser, options );
142+
else {
143+
try (JsonParser osonParser = OSON_JACKSON_FACTORY.createParser( osonBytes )) {
144+
return options.getJsonFormatMapper().readFromSource( getJavaType(), osonParser, options );
145+
}
163146
}
164147
}
165148

hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonArrayJdbcType.java

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.hibernate.type.descriptor.WrapperOptions;
1818
import org.hibernate.type.descriptor.java.BasicPluralJavaType;
1919
import org.hibernate.type.descriptor.java.JavaType;
20+
import org.hibernate.type.descriptor.java.spi.UnknownBasicJavaType;
2021
import org.hibernate.type.format.StringJsonDocumentWriter;
2122

2223
/**
@@ -60,24 +61,33 @@ protected <X> X fromString(String string, JavaType<X> javaType, WrapperOptions o
6061
if ( string == null ) {
6162
return null;
6263
}
63-
return JsonHelper.arrayFromString( javaType, this.getElementJdbcType(), string, options );
64+
if ( ((BasicPluralJavaType<?>) javaType).getElementJavaType() instanceof UnknownBasicJavaType<?> ) {
65+
return options.getJsonFormatMapper().fromString( string, javaType, options );
66+
}
67+
else {
68+
return JsonHelper.arrayFromString( javaType, this.getElementJdbcType(), string, options );
69+
}
6470
}
6571

6672
protected <X> String toString(X value, JavaType<X> javaType, WrapperOptions options) {
67-
final JdbcType elementJdbcType = getElementJdbcType();
68-
final Object[] domainObjects = javaType.unwrap( value, Object[].class, options );
69-
StringBuilder sb = new StringBuilder();
70-
StringJsonDocumentWriter writer = new StringJsonDocumentWriter(new JsonHelper.JsonAppender(sb) );
71-
if ( elementJdbcType instanceof JsonJdbcType jsonElementJdbcType ) {
72-
final EmbeddableMappingType embeddableMappingType = jsonElementJdbcType.getEmbeddableMappingType();
73-
JsonHelper.serializeArray( embeddableMappingType, domainObjects, options, writer);
73+
final JavaType<?> elementJavaType = ( (BasicPluralJavaType<?>) javaType ).getElementJavaType();
74+
if ( elementJavaType instanceof UnknownBasicJavaType<?> ) {
75+
return options.getJsonFormatMapper().toString( value, javaType, options);
7476
}
7577
else {
76-
assert !( elementJdbcType instanceof AggregateJdbcType );
77-
final JavaType<?> elementJavaType = ( (BasicPluralJavaType<?>) javaType ).getElementJavaType();
78-
JsonHelper.serializeArray( elementJavaType, elementJdbcType, domainObjects, options, writer );
78+
final JdbcType elementJdbcType = getElementJdbcType();
79+
final Object[] domainObjects = javaType.unwrap( value, Object[].class, options );
80+
final StringJsonDocumentWriter writer = new StringJsonDocumentWriter();
81+
if ( elementJdbcType instanceof JsonJdbcType jsonElementJdbcType ) {
82+
final EmbeddableMappingType embeddableMappingType = jsonElementJdbcType.getEmbeddableMappingType();
83+
JsonHelper.serializeArray( embeddableMappingType, domainObjects, options, writer );
84+
}
85+
else {
86+
assert !(elementJdbcType instanceof AggregateJdbcType);
87+
JsonHelper.serializeArray( elementJavaType, elementJdbcType, domainObjects, options, writer );
88+
}
89+
return writer.getJson();
7990
}
80-
return sb.toString();
8191
}
8292

8393
@Override

hibernate-core/src/main/java/org/hibernate/type/descriptor/jdbc/JsonJdbcType.java

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ protected <X> X fromString(String string, JavaType<X> javaType, WrapperOptions o
7878
return null;
7979
}
8080
if ( embeddableMappingType != null ) {
81-
return (X) JsonHelper.deserialize(
81+
return JsonHelper.deserialize(
8282
embeddableMappingType,
8383
new StringJsonDocumentReader(string),
8484
javaType.getJavaTypeClass() != Object[].class,
@@ -91,11 +91,10 @@ protected <X> X fromString(String string, JavaType<X> javaType, WrapperOptions o
9191
@Override
9292
public Object createJdbcValue(Object domainValue, WrapperOptions options) throws SQLException {
9393
assert embeddableMappingType != null;
94-
StringBuilder sb = new StringBuilder();
95-
StringJsonDocumentWriter writer = new StringJsonDocumentWriter(new JsonHelper.JsonAppender(sb) );
94+
final StringJsonDocumentWriter writer = new StringJsonDocumentWriter();
9695
try {
97-
JsonHelper.serialize( embeddableMappingType ,domainValue,options, writer );
98-
return writer.toString();
96+
JsonHelper.serialize( embeddableMappingType, domainValue, options, writer );
97+
return writer.getJson();
9998
}
10099
catch (IOException e) {
101100
throw new SQLException( e );
@@ -105,16 +104,15 @@ public Object createJdbcValue(Object domainValue, WrapperOptions options) throws
105104
@Override
106105
public Object[] extractJdbcValues(Object rawJdbcValue, WrapperOptions options) throws SQLException {
107106
assert embeddableMappingType != null;
108-
return JsonHelper.deserialize( embeddableMappingType, new StringJsonDocumentReader( (String)rawJdbcValue ), false, options );
107+
return JsonHelper.deserialize( embeddableMappingType, new StringJsonDocumentReader( (String) rawJdbcValue ), false, options );
109108
}
110109

111110
protected <X> String toString(X value, JavaType<X> javaType, WrapperOptions options) {
112111
if ( embeddableMappingType != null ) {
113112
try {
114-
StringBuilder sb = new StringBuilder();
115-
StringJsonDocumentWriter writer = new StringJsonDocumentWriter(new JsonHelper.JsonAppender(sb) );
116-
JsonHelper.serialize( embeddableMappingType, value, options, writer);
117-
return writer.toString();
113+
final StringJsonDocumentWriter writer = new StringJsonDocumentWriter();
114+
JsonHelper.serialize( embeddableMappingType, value, options, writer );
115+
return writer.getJson();
118116
}
119117
catch (IOException e) {
120118
throw new RuntimeException("Failed to serialize JSON mapping", e );

0 commit comments

Comments
 (0)