Skip to content

Commit c0770f0

Browse files
committed
Add support for JsonUnwrapped
Fix FasterXMLgh-97
1 parent 6129b9b commit c0770f0

File tree

4 files changed

+194
-12
lines changed

4 files changed

+194
-12
lines changed

hibernate4/src/main/java/com/fasterxml/jackson/datatype/hibernate4/HibernateProxySerializer.java

+32-5
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
1919
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
2020
import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
21+
import com.fasterxml.jackson.databind.util.NameTransformer;
2122

2223
import org.hibernate.engine.spi.Mapping;
2324
import org.hibernate.engine.spi.SessionImplementor;
@@ -47,6 +48,7 @@ public class HibernateProxySerializer
4748
protected final boolean _serializeIdentifier;
4849
protected final boolean _nullMissingEntities;
4950
protected final Mapping _mapping;
51+
protected final NameTransformer _unwrapper;
5052

5153
/**
5254
* For efficient serializer lookup, let's use this; most
@@ -62,35 +64,56 @@ public class HibernateProxySerializer
6264

6365
public HibernateProxySerializer(boolean forceLazyLoading)
6466
{
65-
this(forceLazyLoading, false, false, null, null);
67+
this(forceLazyLoading, false, false, null, null, null);
6668
}
6769

6870
public HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier) {
69-
this(forceLazyLoading, serializeIdentifier, false, null, null);
71+
this(forceLazyLoading, serializeIdentifier, false, null, null, null);
7072
}
7173

7274
public HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier, Mapping mapping) {
73-
this(forceLazyLoading, serializeIdentifier, false, mapping, null);
75+
this(forceLazyLoading, serializeIdentifier, false, mapping, null, null);
7476
}
7577

7678
public HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier, boolean nullMissingEntities, Mapping mapping) {
77-
this(forceLazyLoading, serializeIdentifier, nullMissingEntities, mapping, null);
79+
this(forceLazyLoading, serializeIdentifier, nullMissingEntities, mapping, null, null);
7880
}
7981

8082
public HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier, boolean nullMissingEntities, Mapping mapping,
8183
BeanProperty property) {
84+
this(forceLazyLoading, serializeIdentifier, nullMissingEntities, mapping, property, null);
85+
}
86+
87+
88+
protected HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier, boolean nullMissingEntities, Mapping mapping,
89+
BeanProperty property, NameTransformer unwrapper) {
8290
_forceLazyLoading = forceLazyLoading;
8391
_serializeIdentifier = serializeIdentifier;
8492
_nullMissingEntities = nullMissingEntities;
8593
_mapping = mapping;
8694
_dynamicSerializers = PropertySerializerMap.emptyForProperties();
8795
_property = property;
96+
_unwrapper = unwrapper;
8897
}
8998

9099
@Override
91100
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
92101
return new HibernateProxySerializer(this._forceLazyLoading, _serializeIdentifier, _nullMissingEntities,
93-
_mapping, property);
102+
_mapping, property, _unwrapper);
103+
}
104+
105+
@Override
106+
public JsonSerializer<HibernateProxy> unwrappingSerializer(
107+
final NameTransformer unwrapper)
108+
{
109+
return new HibernateProxySerializer(_forceLazyLoading, _serializeIdentifier, _nullMissingEntities,
110+
_mapping, _property, unwrapper == null ? NameTransformer.NOP : unwrapper);
111+
}
112+
113+
@Override
114+
public boolean isUnwrappingSerializer()
115+
{
116+
return _unwrapper != null;
94117
}
95118

96119
/*
@@ -174,6 +197,10 @@ protected JsonSerializer<Object> findSerializer(SerializerProvider provider, Obj
174197
if (_dynamicSerializers != result.map) {
175198
_dynamicSerializers = result.map;
176199
}
200+
if (_unwrapper != null)
201+
{
202+
return result.serializer.unwrappingSerializer(_unwrapper);
203+
}
177204
return result.serializer;
178205
}
179206

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.fasterxml.jackson.datatype.hibernate4;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonUnwrapped;
5+
import com.fasterxml.jackson.core.JsonProcessingException;
6+
import com.fasterxml.jackson.core.type.TypeReference;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.datatype.hibernate4.data.Customer;
9+
import com.fasterxml.jackson.datatype.hibernate4.data.Product;
10+
import org.hibernate.Hibernate;
11+
12+
import javax.persistence.EntityManager;
13+
import javax.persistence.EntityManagerFactory;
14+
import javax.persistence.Persistence;
15+
import java.util.Map;
16+
17+
/**
18+
* Unit test for [#97]
19+
*/
20+
public class UnwrappedTest extends BaseTest
21+
{
22+
static class HasUnwrapped<T>
23+
{
24+
private final T content;
25+
26+
@JsonCreator
27+
public HasUnwrapped(T content)
28+
{
29+
this.content = content;
30+
}
31+
32+
@JsonUnwrapped
33+
public T getContent()
34+
{
35+
return content;
36+
}
37+
}
38+
39+
public void testSimpleUnwrapped() throws JsonProcessingException
40+
{
41+
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistenceUnit");
42+
try {
43+
EntityManager em = emf.createEntityManager();
44+
45+
ObjectMapper mapper = mapperWithModule(true);
46+
47+
Customer customer = em.find(Customer.class, 500);
48+
Product product = customer.getMissingProduct();
49+
assertFalse(Hibernate.isInitialized(product));
50+
51+
String json = mapper.writeValueAsString(new HasUnwrapped<>(product));
52+
53+
assertTrue(Hibernate.isInitialized(product));
54+
assertNotNull(json);
55+
HasUnwrapped<Product> deserialized = mapper.readValue(json, new TypeReference<HasUnwrapped<Product>>(){});
56+
assertTrue(deserialized != null);
57+
assertTrue(deserialized.getContent() != null);
58+
assertTrue(deserialized.getContent().getProductCode() != null);
59+
60+
} finally {
61+
emf.close();
62+
}
63+
}
64+
}

hibernate5/src/main/java/com/fasterxml/jackson/datatype/hibernate5/HibernateProxySerializer.java

+34-7
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import com.fasterxml.jackson.databind.jsontype.TypeSerializer;
1919
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
2020
import com.fasterxml.jackson.databind.ser.impl.PropertySerializerMap;
21+
import com.fasterxml.jackson.databind.util.NameTransformer;
2122

2223
import org.hibernate.engine.spi.Mapping;
2324
import org.hibernate.engine.spi.SessionFactoryImplementor;
@@ -48,6 +49,7 @@ public class HibernateProxySerializer
4849
protected final boolean _serializeIdentifier;
4950
protected final boolean _nullMissingEntities;
5051
protected final Mapping _mapping;
52+
protected final NameTransformer _unwrapper;
5153

5254
/**
5355
* For efficient serializer lookup, let's use this; most
@@ -63,36 +65,57 @@ public class HibernateProxySerializer
6365

6466
public HibernateProxySerializer(boolean forceLazyLoading)
6567
{
66-
this(forceLazyLoading, false, false, null, null);
68+
this(forceLazyLoading, false, false, null, null, null);
6769
}
6870

6971
public HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier) {
70-
this(forceLazyLoading, serializeIdentifier, false, null, null);
72+
this(forceLazyLoading, serializeIdentifier, false, null, null, null);
7173
}
7274

7375
public HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier, Mapping mapping) {
74-
this(forceLazyLoading, serializeIdentifier, false, mapping, null);
76+
this(forceLazyLoading, serializeIdentifier, false, mapping, null, null);
7577
}
7678

7779
public HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier, boolean nullMissingEntities, Mapping mapping) {
78-
this(forceLazyLoading, serializeIdentifier, nullMissingEntities, mapping, null);
80+
this(forceLazyLoading, serializeIdentifier, nullMissingEntities, mapping, null, null);
7981
}
8082

8183
public HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier, boolean nullMissingEntities, Mapping mapping,
82-
BeanProperty property) {
84+
BeanProperty property) {
85+
this(forceLazyLoading, serializeIdentifier, nullMissingEntities, mapping, property, null);
86+
}
87+
88+
89+
protected HibernateProxySerializer(boolean forceLazyLoading, boolean serializeIdentifier, boolean nullMissingEntities, Mapping mapping,
90+
BeanProperty property, NameTransformer unwrapper) {
8391
_forceLazyLoading = forceLazyLoading;
8492
_serializeIdentifier = serializeIdentifier;
8593
_nullMissingEntities = nullMissingEntities;
8694
_mapping = mapping;
8795
_dynamicSerializers = PropertySerializerMap.emptyForProperties();
8896
_property = property;
97+
_unwrapper = unwrapper;
8998
}
9099

91100
@Override
92101
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
93102
return new HibernateProxySerializer(this._forceLazyLoading, _serializeIdentifier, _nullMissingEntities,
94-
_mapping, property);
95-
}
103+
_mapping, property, _unwrapper);
104+
}
105+
106+
@Override
107+
public JsonSerializer<HibernateProxy> unwrappingSerializer(
108+
final NameTransformer unwrapper)
109+
{
110+
return new HibernateProxySerializer(_forceLazyLoading, _serializeIdentifier, _nullMissingEntities,
111+
_mapping, _property, unwrapper == null ? NameTransformer.NOP : unwrapper);
112+
}
113+
114+
@Override
115+
public boolean isUnwrappingSerializer()
116+
{
117+
return _unwrapper != null;
118+
}
96119

97120
/*
98121
/**********************************************************************
@@ -175,6 +198,10 @@ protected JsonSerializer<Object> findSerializer(SerializerProvider provider, Obj
175198
if (_dynamicSerializers != result.map) {
176199
_dynamicSerializers = result.map;
177200
}
201+
if (_unwrapper != null)
202+
{
203+
return result.serializer.unwrappingSerializer(_unwrapper);
204+
}
178205
return result.serializer;
179206
}
180207

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package com.fasterxml.jackson.datatype.hibernate5;
2+
3+
import com.fasterxml.jackson.annotation.JsonCreator;
4+
import com.fasterxml.jackson.annotation.JsonUnwrapped;
5+
import com.fasterxml.jackson.core.JsonProcessingException;
6+
import com.fasterxml.jackson.core.type.TypeReference;
7+
import com.fasterxml.jackson.databind.ObjectMapper;
8+
import com.fasterxml.jackson.datatype.hibernate5.data.Customer;
9+
import com.fasterxml.jackson.datatype.hibernate5.data.Product;
10+
import org.hibernate.Hibernate;
11+
12+
import javax.persistence.EntityManager;
13+
import javax.persistence.EntityManagerFactory;
14+
import javax.persistence.Persistence;
15+
import java.util.Map;
16+
17+
/**
18+
* Unit test for [#97]
19+
*/
20+
public class UnwrappedTest extends BaseTest
21+
{
22+
static class HasUnwrapped<T>
23+
{
24+
private final T content;
25+
26+
@JsonCreator
27+
public HasUnwrapped(T content)
28+
{
29+
this.content = content;
30+
}
31+
32+
@JsonUnwrapped
33+
public T getContent()
34+
{
35+
return content;
36+
}
37+
}
38+
39+
public void testSimpleUnwrapped() throws JsonProcessingException
40+
{
41+
EntityManagerFactory emf = Persistence.createEntityManagerFactory("persistenceUnit");
42+
try {
43+
EntityManager em = emf.createEntityManager();
44+
45+
ObjectMapper mapper = mapperWithModule(true);
46+
47+
Customer customer = em.find(Customer.class, 500);
48+
Product product = customer.getMissingProduct();
49+
assertFalse(Hibernate.isInitialized(product));
50+
51+
String json = mapper.writeValueAsString(new HasUnwrapped<>(product));
52+
53+
assertTrue(Hibernate.isInitialized(product));
54+
assertNotNull(json);
55+
HasUnwrapped<Product> deserialized = mapper.readValue(json, new TypeReference<HasUnwrapped<Product>>(){});
56+
assertTrue(deserialized != null);
57+
assertTrue(deserialized.getContent() != null);
58+
assertTrue(deserialized.getContent().getProductCode() != null);
59+
60+
} finally {
61+
emf.close();
62+
}
63+
}
64+
}

0 commit comments

Comments
 (0)