Skip to content

Commit 259604d

Browse files
committed
HHH-19964 - Add test for json serialization of Object valued attribute mapping
Signed-off-by: Jan Schatteman <jschatte@redhat.com>
1 parent 0d3e834 commit 259604d

File tree

2 files changed

+106
-9
lines changed

2 files changed

+106
-9
lines changed

hibernate-core/src/test/java/org/hibernate/orm/test/inheritance/discriminator/SingleTableAndGenericsTest.java

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
import jakarta.persistence.Inheritance;
2121
import jakarta.persistence.Table;
2222

23+
import java.util.Map;
24+
2325
import static jakarta.persistence.InheritanceType.SINGLE_TABLE;
2426
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
2527
import static org.hibernate.type.SqlTypes.JSON;
28+
import static org.junit.jupiter.api.Assertions.assertTrue;
2629

2730
@DomainModel(
2831
annotatedClasses = {
@@ -37,7 +40,7 @@ public class SingleTableAndGenericsTest {
3740

3841
@Test
3942
public void testIt(SessionFactoryScope scope) {
40-
String payload = "{\"book\": \"1\"}";
43+
Map<String,String> payload = Map.of("book","1");
4144
String aId = "1";
4245

4346
scope.inTransaction(
@@ -53,9 +56,9 @@ public void testIt(SessionFactoryScope scope) {
5356
session -> {
5457
A a = session.find( A.class, aId );
5558
assertThat( a ).isNotNull();
56-
String payload1 = a.getPayload();
59+
Map<?,?> payload1 = a.getPayload();
5760
assertThat( payload1 ).isNotNull();
58-
assertThat( payload1 ).contains( "book" );
61+
assertTrue( payload1.containsKey("book") );
5962
}
6063
);
6164
}
@@ -93,6 +96,9 @@ public void setPayload(T payload) {
9396

9497
@Entity(name = "C")
9598
@DiscriminatorValue("child")
96-
public static class A extends B<String> {
99+
// Changed from <String> to <Map> since the fix for HHH-19969; the restriction '|| type == Object.class' inside
100+
// AbstractFormatMapper.fromString() was removed, so now no cast to String happens, but instead the json is serialized
101+
// to either Map or List (depending on the json format)
102+
public static class A extends B<Map<?,?>> {
97103
}
98104
}

hibernate-core/src/test/java/org/hibernate/orm/test/mapping/basic/JsonMappingTests.java

Lines changed: 96 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import jakarta.persistence.Table;
1212
import jakarta.persistence.criteria.CriteriaUpdate;
1313
import jakarta.persistence.criteria.Root;
14+
import org.assertj.core.api.AssertionsForClassTypes;
1415
import org.hibernate.annotations.JdbcTypeCode;
1516
import org.hibernate.cfg.AvailableSettings;
1617
import org.hibernate.community.dialect.AltibaseDialect;
@@ -42,8 +43,12 @@
4243
import java.nio.charset.StandardCharsets;
4344
import java.sql.Blob;
4445
import java.sql.Clob;
46+
import java.util.ArrayDeque;
47+
import java.util.Dictionary;
48+
import java.util.Hashtable;
4549
import java.util.List;
4650
import java.util.Map;
51+
import java.util.Queue;
4752
import java.util.Set;
4853

4954
import static org.hamcrest.MatcherAssert.assertThat;
@@ -53,12 +58,14 @@
5358
import static org.hamcrest.Matchers.isOneOf;
5459
import static org.hamcrest.Matchers.notNullValue;
5560
import static org.hamcrest.Matchers.nullValue;
61+
import static org.hibernate.type.SqlTypes.JSON;
62+
import static org.junit.jupiter.api.Assertions.assertEquals;
5663

5764
/**
5865
* @author Christian Beikov
5966
* @author Yanming Zhou
6067
*/
61-
@DomainModel(annotatedClasses = JsonMappingTests.EntityWithJson.class)
68+
@DomainModel(annotatedClasses = {JsonMappingTests.EntityWithJson.class, JsonMappingTests.EntityWithObjectJson.class})
6269
@SessionFactory
6370
public abstract class JsonMappingTests {
6471

@@ -76,6 +83,75 @@ public static class Jackson extends JsonMappingTests {
7683
public Jackson() {
7784
super( false );
7885
}
86+
87+
@Test
88+
@JiraKey( "https://hibernate.atlassian.net/browse/HHH-19969" )
89+
public void jsonMappedToObjectTest(SessionFactoryScope scope) {
90+
scope.inTransaction(
91+
session -> {
92+
var entity = new EntityWithObjectJson();
93+
entity.id = 1L;
94+
entity.json = Map.of("a", 1, "b", 2);
95+
session.persist(entity);
96+
97+
entity = new EntityWithObjectJson();
98+
entity.id = 2L;
99+
entity.json = List.<Object>of("c", 11, 22, "d");
100+
session.persist(entity);
101+
102+
entity = new EntityWithObjectJson();
103+
entity.id = 3L;
104+
entity.json = Set.<Object>of("s1", 2, "s3");
105+
session.persist(entity);
106+
107+
entity = new EntityWithObjectJson();
108+
entity.id = 4L;
109+
Queue<Integer> ad = new ArrayDeque<>();
110+
ad.add(2);
111+
ad.add(1);
112+
ad.add(3);
113+
entity.json = ad;
114+
session.persist(entity);
115+
116+
entity = new EntityWithObjectJson();
117+
entity.id = 5L;
118+
Dictionary<Integer, String> ht = new Hashtable<>();
119+
ht.put(1, "one");
120+
ht.put(2, "two");
121+
ht.put(3, "three");
122+
entity.json = ht;
123+
session.persist(entity);
124+
}
125+
);
126+
scope.inTransaction(
127+
session -> {
128+
var entity = session.find( EntityWithObjectJson.class, 1L );
129+
AssertionsForClassTypes.assertThat( entity ).isNotNull();
130+
AssertionsForClassTypes.assertThat( entity.json ).isInstanceOf( Map.class );
131+
assertEquals( 2, ((Map<?,?>)entity.json).size() );
132+
133+
entity = session.find( EntityWithObjectJson.class, 2L );
134+
AssertionsForClassTypes.assertThat( entity ).isNotNull();
135+
AssertionsForClassTypes.assertThat( entity.json ).isInstanceOf( List.class );
136+
assertEquals( 4, ((List<?>)entity.json).size() );
137+
138+
entity = session.find( EntityWithObjectJson.class, 3L );
139+
AssertionsForClassTypes.assertThat( entity ).isNotNull();
140+
AssertionsForClassTypes.assertThat( entity.json ).isInstanceOf( List.class );
141+
assertEquals( 3, ((List<?>)entity.json).size() );
142+
143+
entity = session.find( EntityWithObjectJson.class, 4L );
144+
AssertionsForClassTypes.assertThat( entity ).isNotNull();
145+
AssertionsForClassTypes.assertThat( entity.json ).isInstanceOf( List.class );
146+
assertEquals( 3, ((List<?>)entity.json).size() );
147+
148+
entity = session.find( EntityWithObjectJson.class, 5L );
149+
AssertionsForClassTypes.assertThat( entity ).isNotNull();
150+
AssertionsForClassTypes.assertThat( entity.json ).isInstanceOf( Map.class );
151+
assertEquals( 3, ((Map<?,?>)entity.json).size() );
152+
}
153+
);
154+
}
79155
}
80156

81157
private final Map<String, String> stringMap;
@@ -228,15 +304,13 @@ public void verifyComparisonWorks(SessionFactoryScope scope) {
228304
.get( 0 );
229305
final String jsonText;
230306
try {
231-
if ( nativeJson instanceof Blob ) {
232-
final Blob blob = (Blob) nativeJson;
307+
if ( nativeJson instanceof Blob blob ) {
233308
jsonText = new String(
234309
blob.getBytes( 1L, (int) blob.length() ),
235310
StandardCharsets.UTF_8
236311
);
237312
}
238-
else if ( nativeJson instanceof Clob ) {
239-
final Clob jsonClob = (Clob) nativeJson;
313+
else if ( nativeJson instanceof Clob jsonClob ) {
240314
jsonText = jsonClob.getSubString( 1L, (int) jsonClob.length() );
241315
}
242316
else {
@@ -363,4 +437,21 @@ public int hashCode() {
363437
return string != null ? string.hashCode() : 0;
364438
}
365439
}
440+
441+
@Entity
442+
public static class EntityWithObjectJson {
443+
@Id
444+
long id;
445+
446+
@JdbcTypeCode(JSON)
447+
Object json;
448+
449+
public EntityWithObjectJson() {
450+
}
451+
452+
public EntityWithObjectJson(long id, Object json) {
453+
this.id = id;
454+
this.json = json;
455+
}
456+
}
366457
}

0 commit comments

Comments
 (0)