Skip to content

Commit 60155d1

Browse files
committed
HHH-17404 add array of embeddable support
1 parent 775fdeb commit 60155d1

File tree

5 files changed

+380
-4
lines changed

5 files changed

+380
-4
lines changed

hibernate-core/src/main/java/org/hibernate/dialect/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;
@@ -265,7 +266,15 @@ private static <X> X consumeJsonDocumentItems(JsonDocumentReader reader, Embedda
265266
objectArrayResult = new Object[embeddableMappingType.getJdbcValueCount()+ ( embeddableMappingType.isPolymorphic() ? 1 : 0 )];
266267
objectArrays.push( objectArrayResult );
267268

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

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@
134134
import static org.hibernate.type.SqlTypes.DATE;
135135
import static org.hibernate.type.SqlTypes.DECIMAL;
136136
import static org.hibernate.type.SqlTypes.DOUBLE;
137-
import static org.hibernate.type.SqlTypes.DURATION;
138137
import static org.hibernate.type.SqlTypes.FLOAT;
139138
import static org.hibernate.type.SqlTypes.GEOMETRY;
140139
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/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)