Skip to content

Commit ae52e3e

Browse files
committed
HHH-17404 add array of embeddable support
1 parent 7593be8 commit ae52e3e

File tree

5 files changed

+380
-4
lines changed

5 files changed

+380
-4
lines changed

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,6 @@
146146
import static org.hibernate.type.SqlTypes.DATE;
147147
import static org.hibernate.type.SqlTypes.DECIMAL;
148148
import static org.hibernate.type.SqlTypes.DOUBLE;
149-
import static org.hibernate.type.SqlTypes.DURATION;
150149
import static org.hibernate.type.SqlTypes.FLOAT;
151150
import static org.hibernate.type.SqlTypes.GEOMETRY;
152151
import static org.hibernate.type.SqlTypes.INTEGER;

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

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

7+
import com.fasterxml.jackson.core.JsonFactory;
78
import com.fasterxml.jackson.core.JsonParser;
89
import oracle.jdbc.OracleType;
910
import oracle.jdbc.driver.DatabaseError;
@@ -12,6 +13,7 @@
1213
import oracle.sql.json.OracleJsonFactory;
1314
import oracle.sql.json.OracleJsonGenerator;
1415

16+
import oracle.sql.json.OracleJsonParser;
1517
import org.hibernate.internal.CoreLogging;
1618
import org.hibernate.internal.CoreMessageLogger;
1719
import org.hibernate.metamodel.mapping.EmbeddableMappingType;
@@ -26,6 +28,7 @@
2628
import org.hibernate.type.descriptor.jdbc.JdbcType;
2729
import org.hibernate.type.descriptor.jdbc.JsonJdbcType;
2830
import org.hibernate.type.format.FormatMapper;
31+
import org.hibernate.type.format.OsonDocumentReader;
2932
import org.hibernate.type.format.OsonDocumentWriter;
3033

3134
import java.io.ByteArrayOutputStream;
@@ -125,9 +128,19 @@ public <X> ValueExtractor<X> getExtractor(JavaType<X> javaType) {
125128

126129
private X fromOson(InputStream osonBytes, WrapperOptions options) throws Exception {
127130
FormatMapper mapper = options.getJsonFormatMapper();
128-
JsonParser osonParser = osonFactory.createParser( osonBytes );
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 );
138+
}
139+
}
140+
try (JsonParser oParser = ((JsonFactory)osonFactory).createParser( osonBytes )) {
141+
return mapper.readFromSource( getJavaType(), oParser, options);
142+
}
129143

130-
return mapper.readFromSource( getJavaType(), osonParser, options);
131144
}
132145

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

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

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import org.hibernate.type.descriptor.jdbc.AggregateJdbcType;
3737
import org.hibernate.type.descriptor.jdbc.ArrayJdbcType;
3838
import org.hibernate.type.descriptor.jdbc.JdbcType;
39+
import org.hibernate.type.descriptor.jdbc.JsonJdbcType;
3940
import org.hibernate.type.format.JsonDocumentItemType;
4041
import org.hibernate.type.format.JsonDocumentReader;
4142
import org.hibernate.type.format.JsonDocumentWriter;
@@ -264,7 +265,15 @@ private static <X> X consumeJsonDocumentItems(JsonDocumentReader reader, Embedda
264265
objectArrayResult = new Object[embeddableMappingType.getJdbcValueCount()+ ( embeddableMappingType.isPolymorphic() ? 1 : 0 )];
265266
objectArrays.push( objectArrayResult );
266267

267-
while(reader.hasNext()) {
268+
// We loop on two conditions:
269+
// - the parser still has tokens left
270+
// - the type stack is not empty
271+
// Even if the reader has some tokens left, if the type stack is empty,
272+
// that means that we have to stop parsing. That may be the case while parsing an object of object array,
273+
// the array is not empty, but we ae done parsing that specific object.
274+
// When we encounter OBJECT_END the current type is popped out of the stack. When parsing one object of an array we may end up
275+
// having an empty stack. Next Objects are parsed in the next round.
276+
while(reader.hasNext() && !embeddableMappingTypes.isEmpty()) {
268277
JsonDocumentItemType type = reader.next();
269278
switch (type) {
270279
case VALUE_KEY:
@@ -462,6 +471,15 @@ public static <X> X deserializeArray(
462471
case VALUE:
463472
arrayList.add( adapter.fromValue(jdbcJavaType, elementJdbcType ,reader, options) );
464473
break;
474+
case OBJECT_START:
475+
assert elementJdbcType instanceof JsonJdbcType;
476+
Object o = deserialize(
477+
((JsonJdbcType) elementJdbcType).getEmbeddableMappingType(),
478+
reader,
479+
true,
480+
options);
481+
arrayList.add(o);
482+
break;
465483
default:
466484
throw new UnsupportedOperationException( "Unexpected JSON type " + type );
467485
}

hibernate-core/src/test/java/org/hibernate/orm/test/mapping/embeddable/EmbeddableAggregate.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,14 @@ public void setMutableValue(MutableValue mutableValue) {
292292
this.mutableValue = mutableValue;
293293
}
294294

295+
static void assertArraysEquals(EmbeddableAggregate [] a1, EmbeddableAggregate []a2) {
296+
Assertions.assertTrue( (a1 == null && a2 == null) || (a1 != null && a2 != null) );
297+
Assertions.assertEquals( a1.length, a2.length );
298+
for (int i = 0; i < a1.length; i++) {
299+
assertEquals(a1[i], a2[i]);
300+
}
301+
}
302+
295303
static void assertEquals(EmbeddableAggregate a1, EmbeddableAggregate a2) {
296304
Assertions.assertEquals( a1.theInt, a2.theInt );
297305
Assertions.assertEquals( a1.theDouble, a2.theDouble );
@@ -338,6 +346,13 @@ static void assertEquals(EmbeddableAggregate a1, EmbeddableAggregate a2) {
338346
}
339347
}
340348

349+
public static EmbeddableAggregate[] createAggregateArray1() {
350+
return new EmbeddableAggregate[] {createAggregate1(),createAggregate2()};
351+
}
352+
public static EmbeddableAggregate[] createAggregateArray2() {
353+
return new EmbeddableAggregate[] {createAggregate3()};
354+
}
355+
341356
public static EmbeddableAggregate createAggregate1() {
342357
final EmbeddableAggregate aggregate = new EmbeddableAggregate();
343358
aggregate.theBoolean = true;

0 commit comments

Comments
 (0)