DATAREST-1321 - Lookup types can now produce non-String reference values.
Previously we assumed lookup types to always result in String based values. We now loosen that constraint to also allow other scalar types, mostly targeting numeric types like long and integer.
This commit is contained in:
@@ -16,12 +16,16 @@
|
||||
package org.springframework.data.rest.webmvc.json;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -32,9 +36,11 @@ import org.springframework.core.convert.TypeDescriptor;
|
||||
import org.springframework.data.keyvalue.core.mapping.context.KeyValueMappingContext;
|
||||
import org.springframework.data.mapping.PersistentProperty;
|
||||
import org.springframework.data.mapping.context.PersistentEntities;
|
||||
import org.springframework.data.repository.support.RepositoryInvoker;
|
||||
import org.springframework.data.repository.support.RepositoryInvokerFactory;
|
||||
import org.springframework.data.rest.core.UriToEntityConverter;
|
||||
import org.springframework.data.rest.core.mapping.ResourceMappings;
|
||||
import org.springframework.data.rest.core.support.EntityLookup;
|
||||
import org.springframework.data.rest.core.support.SelfLinkProvider;
|
||||
import org.springframework.data.rest.core.util.Java8PluginRegistry;
|
||||
import org.springframework.data.rest.webmvc.EmbeddedResourcesAssembler;
|
||||
@@ -49,6 +55,8 @@ import org.springframework.hateoas.ResourceProcessor;
|
||||
import org.springframework.hateoas.UriTemplate;
|
||||
import org.springframework.hateoas.mvc.ResourceProcessorInvoker;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
@@ -69,6 +77,7 @@ public class PersistentEntityJackson2ModuleUnitTests {
|
||||
@Mock EntityLinks entityLinks;
|
||||
@Mock ResourceMappings mappings;
|
||||
@Mock SelfLinkProvider selfLinks;
|
||||
@Mock RepositoryInvokerFactory factory;
|
||||
|
||||
PersistentEntities persistentEntities;
|
||||
ObjectMapper mapper;
|
||||
@@ -90,9 +99,9 @@ public class PersistentEntityJackson2ModuleUnitTests {
|
||||
SimpleModule module = new SimpleModule();
|
||||
|
||||
module.setSerializerModifier(new AssociationOmittingSerializerModifier(persistentEntities, associations,
|
||||
nestedEntitySerializer, new LookupObjectSerializer(Java8PluginRegistry.empty())));
|
||||
module.setDeserializerModifier(new AssociationUriResolvingDeserializerModifier(persistentEntities, associations,
|
||||
converter, mock(RepositoryInvokerFactory.class)));
|
||||
nestedEntitySerializer, new LookupObjectSerializer(Java8PluginRegistry.of(Arrays.asList(new HomeLookup())))));
|
||||
module.setDeserializerModifier(
|
||||
new AssociationUriResolvingDeserializerModifier(persistentEntities, associations, converter, factory));
|
||||
|
||||
this.mapper = new ObjectMapper();
|
||||
this.mapper.registerModule(module);
|
||||
@@ -135,13 +144,71 @@ public class PersistentEntityJackson2ModuleUnitTests {
|
||||
assertThat(petOwner.getPet()).isNotNull();
|
||||
}
|
||||
|
||||
@Test // DATAREST-1321
|
||||
public void allowsNumericIdsForLookupTypes() throws Exception {
|
||||
|
||||
RepositoryInvoker invoker = mock(RepositoryInvoker.class);
|
||||
when(invoker.invokeFindById(any(Long.class))).thenReturn(Optional.of(new Home()));
|
||||
|
||||
when(factory.getInvokerFor(Home.class)).thenReturn(invoker);
|
||||
|
||||
PersistentProperty<?> property = persistentEntities.getRequiredPersistentEntity(PetOwner.class)
|
||||
.getRequiredPersistentProperty("home");
|
||||
|
||||
when(associations.isLookupType(property)).thenReturn(true);
|
||||
|
||||
PetOwner petOwner = mapper.readValue("{\"home\": 1 }", PetOwner.class);
|
||||
|
||||
assertThat(petOwner).isNotNull();
|
||||
assertThat(petOwner.getHome()).isInstanceOf(Home.class);
|
||||
}
|
||||
|
||||
@Test // DATAREST-1321
|
||||
public void serializesNonStringLookupValues() throws Exception {
|
||||
|
||||
// Given Pet defined as lookup type
|
||||
PersistentProperty<?> property = persistentEntities.getRequiredPersistentEntity(PetOwner.class)
|
||||
.getRequiredPersistentProperty("home");
|
||||
when(associations.isLookupType(property)).thenReturn(true);
|
||||
|
||||
// When a Pet is rendered
|
||||
PetOwner owner = new PetOwner();
|
||||
owner.home = new Home();
|
||||
|
||||
String result = mapper.writeValueAsString(owner);
|
||||
|
||||
// The it appears as numeric value
|
||||
assertThat(JsonPath.parse(result).read("$.home", Integer.class)) //
|
||||
.isEqualTo(41);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
private static class HomeLookup implements EntityLookup<Home> {
|
||||
|
||||
@Override
|
||||
public Object getResourceIdentifier(Home entity) {
|
||||
return 41;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supports(Class<?> delimiter) {
|
||||
return delimiter.equals(Home.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Home> lookupEntity(Object id) {
|
||||
return Optional.of(new Home());
|
||||
}
|
||||
}
|
||||
|
||||
@Getter
|
||||
@JsonInclude(Include.NON_NULL)
|
||||
static class PetOwner {
|
||||
|
||||
Pet pet;
|
||||
|
||||
public Pet getPet() {
|
||||
return pet;
|
||||
}
|
||||
Home home;
|
||||
}
|
||||
|
||||
@JsonTypeInfo(include = JsonTypeInfo.As.PROPERTY, use = JsonTypeInfo.Id.MINIMAL_CLASS)
|
||||
@@ -149,6 +216,8 @@ public class PersistentEntityJackson2ModuleUnitTests {
|
||||
|
||||
static class Cat extends Pet {}
|
||||
|
||||
static class Home {}
|
||||
|
||||
static class Sample {
|
||||
public @JsonProperty("foo") String name;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user