Skip to content

Commit db160c4

Browse files
committed
GH-1926 - Avoid wrapping nested entities ultimately to represent a value.
NestedEntitySerializer now skips the wrapping into an EntityModel if the target serializer is a JsonValueSerializer as EntityModel requires the value to ultimately resolve into key value pairs as it's only enriching something that's rendered as JSON document with hypermedia elements.
1 parent 96a6e47 commit db160c4

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

spring-data-rest-webmvc/src/main/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2Module.java

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import com.fasterxml.jackson.databind.module.SimpleModule;
9090
import com.fasterxml.jackson.databind.ser.BeanPropertyWriter;
9191
import com.fasterxml.jackson.databind.ser.BeanSerializerModifier;
92+
import com.fasterxml.jackson.databind.ser.std.JsonValueSerializer;
9293
import com.fasterxml.jackson.databind.ser.std.StdScalarSerializer;
9394
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
9495
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@@ -354,7 +355,7 @@ public void serialize(Object value, JsonGenerator gen, SerializerProvider provid
354355
List<Object> resources = new ArrayList<Object>();
355356

356357
for (Object element : source) {
357-
resources.add(toModel(element));
358+
resources.add(toModel(element, provider));
358359
}
359360

360361
provider.defaultSerializeValue(resources, gen);
@@ -365,13 +366,13 @@ public void serialize(Object value, JsonGenerator gen, SerializerProvider provid
365366
Map<Object, Object> resources = CollectionFactory.createApproximateMap(value.getClass(), source.size());
366367

367368
for (Entry<?, ?> entry : source.entrySet()) {
368-
resources.put(entry.getKey(), toModel(entry.getValue()));
369+
resources.put(entry.getKey(), toModel(entry.getValue(), provider));
369370
}
370371

371372
provider.defaultSerializeValue(resources, gen);
372373

373374
} else {
374-
provider.defaultSerializeValue(toModel(value), gen);
375+
provider.defaultSerializeValue(toModel(value, provider), gen);
375376
}
376377
}
377378

@@ -385,7 +386,13 @@ public void serializeWithType(Object value, JsonGenerator gen, SerializerProvide
385386
serialize(value, gen, provider);
386387
}
387388

388-
private EntityModel<Object> toModel(Object value) {
389+
private Object toModel(Object value, SerializerProvider provider) throws JsonMappingException {
390+
391+
JsonSerializer<Object> serializer = provider.findValueSerializer(value.getClass());
392+
393+
if (JsonValueSerializer.class.isInstance(serializer)) {
394+
return value;
395+
}
389396

390397
PersistentEntity<?, ?> entity = entities.getRequiredPersistentEntity(value.getClass());
391398

spring-data-rest-webmvc/src/test/java/org/springframework/data/rest/webmvc/json/PersistentEntityJackson2ModuleUnitTests.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import static org.mockito.ArgumentMatchers.*;
2020
import static org.mockito.Mockito.*;
2121

22+
import lombok.Data;
2223
import lombok.Getter;
2324

2425
import java.io.IOException;
@@ -58,6 +59,7 @@
5859
import com.fasterxml.jackson.annotation.JsonInclude.Include;
5960
import com.fasterxml.jackson.annotation.JsonProperty;
6061
import com.fasterxml.jackson.annotation.JsonTypeInfo;
62+
import com.fasterxml.jackson.annotation.JsonValue;
6163
import com.fasterxml.jackson.databind.ObjectMapper;
6264
import com.fasterxml.jackson.databind.module.SimpleModule;
6365
import com.jayway.jsonpath.JsonPath;
@@ -89,6 +91,7 @@ public void setUp() {
8991
mappingContext.getPersistentEntity(SampleWithAdditionalGetters.class);
9092
mappingContext.getPersistentEntity(PersistentEntityJackson2ModuleUnitTests.PetOwner.class);
9193
mappingContext.getPersistentEntity(Immutable.class);
94+
mappingContext.getPersistentEntity(Wrapper.class);
9295

9396
this.persistentEntities = new PersistentEntities(Arrays.asList(mappingContext));
9497

@@ -197,6 +200,16 @@ public void customizesDeserializerForCreatorProperties() throws Exception {
197200
TypeDescriptor.valueOf(Home.class));
198201
}
199202

203+
@Test // GH-1926
204+
public void doesNotWrapJsonValueTypesIntoEntityModel() throws Exception {
205+
206+
Wrapper wrapper = new Wrapper();
207+
wrapper.value = new ValueType();
208+
wrapper.value.value = "sample";
209+
210+
assertThat(mapper.writeValueAsString(wrapper)).isEqualTo("{\"value\":\"sample\"}");
211+
}
212+
200213
/**
201214
* @author Oliver Gierke
202215
*/
@@ -257,4 +270,15 @@ public Immutable(@JsonProperty("home") Home home) {
257270
this.home = home;
258271
}
259272
}
273+
274+
// GH-1926
275+
276+
@Data
277+
static class Wrapper {
278+
ValueType value;
279+
}
280+
281+
static class ValueType {
282+
@JsonValue String value;
283+
}
260284
}

0 commit comments

Comments
 (0)