DATAREST-1064 - Adapt to API changes in repository interfaces.
Additional cleanups in QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver to make sure a QuerydslRepositoryInvokerAdapter is only applied if the QuerydslPredicateBuilder actually exposes a predicate. Extracted a couple of methods to make sure the mapping pipeline reads nicely.
This commit is contained in:
@@ -123,6 +123,6 @@ public class UriToEntityConverter implements ConditionalGenericConverter {
|
||||
"Cannot resolve URI " + uri + ". Is it local or remote? Only local URIs are resolvable."));
|
||||
}
|
||||
|
||||
return invokerFactory.getInvokerFor(targetType.getType()).invokeFindOne(parts[parts.length - 1]).orElse(null);
|
||||
return invokerFactory.getInvokerFor(targetType.getType()).invokeFindById(parts[parts.length - 1]).orElse(null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.Value;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
@@ -31,6 +30,7 @@ import org.springframework.data.repository.core.support.AbstractRepositoryMetada
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.rest.core.config.EntityLookupRegistrar.LookupRegistrar.Lookup;
|
||||
import org.springframework.data.rest.core.support.EntityLookup;
|
||||
import org.springframework.data.util.StreamUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
@@ -42,16 +42,16 @@ import org.springframework.util.Assert;
|
||||
*/
|
||||
class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
|
||||
private final List<LookupInformation<Object, Serializable, Repository<? extends Object, ?>>> lookupInformation = new ArrayList<LookupInformation<Object, Serializable, Repository<?, ?>>>();
|
||||
private final List<Class<?>> lookupTypes = new ArrayList<Class<?>>();
|
||||
private final List<LookupInformation<Object, Object, Repository<? extends Object, ?>>> lookupInformation = new ArrayList<>();
|
||||
private final List<Class<?>> lookupTypes = new ArrayList<>();
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.rest.core.config.EntityLookupRegistrar#forRepository(java.lang.Class, org.springframework.core.convert.converter.Converter, org.springframework.data.rest.core.config.EntityLookupRegistrar.LookupRegistrar.Lookup)
|
||||
*/
|
||||
@Override
|
||||
public <T, ID extends Serializable, R extends Repository<T, ?>> EntityLookupRegistrar forRepository(
|
||||
Class<R> repositoryType, Converter<T, ID> converter, Lookup<R, ID> lookup) {
|
||||
public <T, ID, R extends Repository<T, ?>> EntityLookupRegistrar forRepository(Class<R> repositoryType,
|
||||
Converter<T, ID> converter, Lookup<R, ID> lookup) {
|
||||
|
||||
new MappingBuilder<T, ID, R>(repositoryType).withIdMapping(converter).withLookup(lookup);
|
||||
return this;
|
||||
@@ -62,8 +62,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
* @see org.springframework.data.rest.core.config.EntityLookupRegistrar#forValueRepository(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T, ID extends Serializable, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forLookupRepository(
|
||||
Class<R> type) {
|
||||
public <T, ID, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forLookupRepository(Class<R> type) {
|
||||
this.lookupTypes.add(AbstractRepositoryMetadata.getMetadata(type).getDomainType());
|
||||
return forRepository(type);
|
||||
}
|
||||
@@ -73,8 +72,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
* @see org.springframework.data.rest.core.config.EntityLookupRegistrar#forRepository(java.lang.Class)
|
||||
*/
|
||||
@Override
|
||||
public <T, ID extends Serializable, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forRepository(
|
||||
Class<R> type) {
|
||||
public <T, ID, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forRepository(Class<R> type) {
|
||||
return new MappingBuilder<T, ID, R>(type);
|
||||
}
|
||||
|
||||
@@ -83,8 +81,8 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
* @see org.springframework.data.rest.core.config.EntityLookupRegistrar#forValueRepository(java.lang.Class, org.springframework.core.convert.converter.Converter, org.springframework.data.rest.core.config.EntityLookupRegistrar.LookupRegistrar.Lookup)
|
||||
*/
|
||||
@Override
|
||||
public <T, ID extends Serializable, R extends Repository<T, ?>> EntityLookupRegistrar forValueRepository(
|
||||
Class<R> type, Converter<T, ID> identifierMapping, Lookup<R, ID> lookup) {
|
||||
public <T, ID, R extends Repository<T, ?>> EntityLookupRegistrar forValueRepository(Class<R> type,
|
||||
Converter<T, ID> identifierMapping, Lookup<R, ID> lookup) {
|
||||
|
||||
this.lookupTypes.add(AbstractRepositoryMetadata.getMetadata(type).getDomainType());
|
||||
return forRepository(type, identifierMapping, lookup);
|
||||
@@ -96,7 +94,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
private class MappingBuilder<T, ID extends Serializable, R extends Repository<T, ?>>
|
||||
private class MappingBuilder<T, ID, R extends Repository<T, ?>>
|
||||
implements LookupRegistrar<T, ID, R>, IdMappingRegistrar<T, R> {
|
||||
|
||||
private @NonNull final Class<R> repositoryType;
|
||||
@@ -125,8 +123,8 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
@SuppressWarnings("unchecked")
|
||||
public EntityLookupRegistrar withLookup(Lookup<R, ID> lookup) {
|
||||
|
||||
EntityLookupConfiguration.this.lookupInformation.add(
|
||||
(LookupInformation<Object, Serializable, Repository<? extends Object, ?>>) new LookupInformation<T, ID, R>(
|
||||
EntityLookupConfiguration.this.lookupInformation
|
||||
.add((LookupInformation<Object, Object, Repository<? extends Object, ?>>) new LookupInformation<T, ID, R>(
|
||||
repositoryType, idMapping, lookup));
|
||||
|
||||
return EntityLookupConfiguration.this;
|
||||
@@ -137,7 +135,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
* @see org.springframework.data.rest.core.config.EntityLookupRegistrar.IdMappingRegistrar#withIdMapping(org.springframework.core.convert.converter.Converter)
|
||||
*/
|
||||
@Override
|
||||
public <ID2 extends Serializable> LookupRegistrar<T, ID2, R> withIdMapping(Converter<T, ID2> idMapping) {
|
||||
public <ID2> LookupRegistrar<T, ID2, R> withIdMapping(Converter<T, ID2> idMapping) {
|
||||
return new MappingBuilder<T, ID2, R>(repositoryType, idMapping);
|
||||
}
|
||||
}
|
||||
@@ -152,13 +150,9 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
|
||||
Assert.notNull(repositories, "Repositories must not be null!");
|
||||
|
||||
List<EntityLookup<?>> lookups = new ArrayList<EntityLookup<?>>(lookupInformation.size());
|
||||
|
||||
for (LookupInformation<Object, Serializable, Repository<? extends Object, ?>> information : lookupInformation) {
|
||||
lookups.add(new RepositoriesEntityLookup<Object>(repositories, information));
|
||||
}
|
||||
|
||||
return lookups;
|
||||
return lookupInformation.stream()//
|
||||
.map(it -> new RepositoriesEntityLookup<>(repositories, it))//
|
||||
.collect(StreamUtils.toUnmodifiableList());
|
||||
}
|
||||
|
||||
public boolean isLookupType(Class<?> type) {
|
||||
@@ -172,7 +166,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
*/
|
||||
private static class RepositoriesEntityLookup<T> implements EntityLookup<T> {
|
||||
|
||||
private final LookupInformation<Object, Serializable, Repository<? extends T, ?>> lookupInfo;
|
||||
private final LookupInformation<Object, Object, Repository<? extends T, ?>> lookupInfo;
|
||||
private final Repository<? extends T, ?> repository;
|
||||
private final Class<?> domainType;
|
||||
|
||||
@@ -184,7 +178,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public RepositoriesEntityLookup(Repositories repositories,
|
||||
LookupInformation<Object, Serializable, Repository<? extends T, ?>> lookupInformation) {
|
||||
LookupInformation<Object, Object, Repository<? extends T, ?>> lookupInformation) {
|
||||
|
||||
Assert.notNull(repositories, "Repositories must not be null!");
|
||||
Assert.notNull(lookupInformation, "LookupInformation must not be null!");
|
||||
@@ -205,7 +199,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
* @see org.springframework.data.rest.core.support.EntityLookup#getResourceIdentifier(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public Serializable getResourceIdentifier(T entity) {
|
||||
public Object getResourceIdentifier(T entity) {
|
||||
return lookupInfo.getIdentifierMapping().convert(entity);
|
||||
}
|
||||
|
||||
@@ -214,7 +208,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
* @see org.springframework.data.rest.core.support.EntityLookup#lookupEntity(java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
public Optional<Object> lookupEntity(Serializable id) {
|
||||
public Optional<Object> lookupEntity(Object id) {
|
||||
return Optional.ofNullable(lookupInfo.getLookup().lookup(repository, id));
|
||||
}
|
||||
|
||||
@@ -229,7 +223,7 @@ class EntityLookupConfiguration implements EntityLookupRegistrar {
|
||||
}
|
||||
|
||||
@Value
|
||||
private static class LookupInformation<T, ID extends Serializable, R extends Repository<? extends T, ?>> {
|
||||
private static class LookupInformation<T, ID, R extends Repository<? extends T, ?>> {
|
||||
|
||||
private final Class<R> repositoryType;
|
||||
private final Converter<T, ID> identifierMapping;
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.config;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.rest.core.config.EntityLookupRegistrar.LookupRegistrar.Lookup;
|
||||
@@ -36,7 +34,7 @@ public interface EntityLookupRegistrar {
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
<T, ID extends Serializable, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forRepository(Class<R> type);
|
||||
<T, ID, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forRepository(Class<R> type);
|
||||
|
||||
/**
|
||||
* Starts building a custom {@link EntityLookup} for the given repository type and registers the domain type of the
|
||||
@@ -45,7 +43,7 @@ public interface EntityLookupRegistrar {
|
||||
* @param type must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
<T, ID extends Serializable, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forLookupRepository(Class<R> type);
|
||||
<T, ID, R extends Repository<T, ?>> IdMappingRegistrar<T, R> forLookupRepository(Class<R> type);
|
||||
|
||||
interface IdMappingRegistrar<T, R extends Repository<T, ?>> {
|
||||
|
||||
@@ -55,7 +53,7 @@ public interface EntityLookupRegistrar {
|
||||
* @param mapping must not be {@literal null}.
|
||||
* @return
|
||||
*/
|
||||
<ID extends Serializable> LookupRegistrar<T, ID, R> withIdMapping(Converter<T, ID> mapping);
|
||||
<ID> LookupRegistrar<T, ID, R> withIdMapping(Converter<T, ID> mapping);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,7 +63,7 @@ public interface EntityLookupRegistrar {
|
||||
* @param identifierMapping must not be {@literal null}.
|
||||
* @param lookup must not be {@literal null}.
|
||||
*/
|
||||
<T, ID extends Serializable, R extends Repository<T, ?>> EntityLookupRegistrar forRepository(Class<R> type,
|
||||
<T, ID, R extends Repository<T, ?>> EntityLookupRegistrar forRepository(Class<R> type,
|
||||
Converter<T, ID> identifierMapping, Lookup<R, ID> lookup);
|
||||
|
||||
/**
|
||||
@@ -76,10 +74,10 @@ public interface EntityLookupRegistrar {
|
||||
* @param identifierMapping must not be {@literal null}.
|
||||
* @param lookup must not be {@literal null}.
|
||||
*/
|
||||
<T, ID extends Serializable, R extends Repository<T, ?>> EntityLookupRegistrar forValueRepository(Class<R> type,
|
||||
<T, ID, R extends Repository<T, ?>> EntityLookupRegistrar forValueRepository(Class<R> type,
|
||||
Converter<T, ID> identifierMapping, Lookup<R, ID> lookup);
|
||||
|
||||
interface LookupRegistrar<T, ID extends Serializable, R extends Repository<T, ?>> {
|
||||
interface LookupRegistrar<T, ID, R extends Repository<T, ?>> {
|
||||
|
||||
/**
|
||||
* Registers the given {@link Lookup} to obtain entity instances.
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.springframework.data.rest.core.support;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.plugin.core.Plugin;
|
||||
@@ -42,7 +41,7 @@ public interface EntityLookup<T> extends Plugin<Class<?>> {
|
||||
* @param entity will never be {@literal null}.
|
||||
* @return must not be {@literal null}.
|
||||
*/
|
||||
Serializable getResourceIdentifier(T entity);
|
||||
Object getResourceIdentifier(T entity);
|
||||
|
||||
/**
|
||||
* Returns the entity instance to be used if an entity with the given identifier value is requested. Implementations
|
||||
@@ -55,5 +54,5 @@ public interface EntityLookup<T> extends Plugin<Class<?>> {
|
||||
* @param id will never be {@literal null}.
|
||||
* @return can be {@literal null}.
|
||||
*/
|
||||
Optional<Object> lookupEntity(Serializable id);
|
||||
Optional<Object> lookupEntity(Object id);
|
||||
}
|
||||
|
||||
@@ -85,12 +85,13 @@ public class UnwrappingRepositoryInvokerFactory implements RepositoryInvokerFact
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeFindOne(java.io.Serializable)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> Optional<T> invokeFindOne(Serializable id) {
|
||||
public <T> Optional<T> invokeFindById(Object id) {
|
||||
|
||||
return (Optional<T>) lookup//
|
||||
.map(it -> it.lookupEntity(id).orElse(Optional.empty()))//
|
||||
.orElseGet(() -> delegate.invokeFindOne(id));
|
||||
.orElseGet(() -> delegate.invokeFindById(id));
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -139,13 +140,13 @@ public class UnwrappingRepositoryInvokerFactory implements RepositoryInvokerFact
|
||||
return delegate.hasSaveMethod();
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeDelete(java.io.Serializable)
|
||||
* @see org.springframework.data.repository.support.RepositoryInvoker#invokeDeleteById(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
public void invokeDelete(Serializable id) {
|
||||
delegate.invokeDelete(id);
|
||||
public void invokeDeleteById(Object id) {
|
||||
delegate.invokeDeleteById(id);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -105,7 +105,7 @@ public class UriToEntityConverterUnitTests {
|
||||
Entity reference = new Entity();
|
||||
|
||||
RepositoryInvoker invoker = mock(RepositoryInvoker.class);
|
||||
doReturn(Optional.of(reference)).when(invoker).invokeFindOne("1");
|
||||
doReturn(Optional.of(reference)).when(invoker).invokeFindById("1");
|
||||
doReturn(invoker).when(invokerFactory).getInvokerFor(ENTITY_TYPE.getType());
|
||||
|
||||
assertThat(converter.convert(URI.create("/foo/bar/1"), URI_TYPE, ENTITY_TYPE)).isEqualTo((Object) reference);
|
||||
|
||||
@@ -32,10 +32,10 @@ public interface OrderRepository extends CrudRepository<Order, UUID> {
|
||||
@Override
|
||||
<S extends Order> S save(S entity);
|
||||
|
||||
/*
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.repository.CrudRepository#findOne(java.io.Serializable)
|
||||
* @see org.springframework.data.repository.CrudRepository#findById(java.lang.Object)
|
||||
*/
|
||||
@Override
|
||||
Optional<Order> findOne(UUID id);
|
||||
Optional<Order> findById(UUID id);
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ public class CrudMethodsSupportedHttpMethodsUnitTests {
|
||||
|
||||
@Override
|
||||
@RestResource(exported = false)
|
||||
Optional<Object> findOne(Long id);
|
||||
Optional<Object> findById(Long id);
|
||||
}
|
||||
|
||||
interface NoFindOne extends Repository<Object, Long> {
|
||||
|
||||
@@ -86,7 +86,7 @@ public class UnwrappingRepositoryInvokerFactoryUnitTests {
|
||||
when(delegate.getInvokerFor(Profile.class)).thenReturn(invoker);
|
||||
|
||||
factory = new UnwrappingRepositoryInvokerFactory(delegate, Arrays.asList(lookup));
|
||||
factory.getInvokerFor(Profile.class).invokeFindOne(1L);
|
||||
factory.getInvokerFor(Profile.class).invokeFindById(1L);
|
||||
|
||||
verify(lookup, times(1)).lookupEntity(eq(1L));
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.test.web.servlet.ResultActions;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
|
||||
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
|
||||
@@ -62,7 +63,7 @@ public abstract class CommonWebTests extends AbstractWebIntegrationTests {
|
||||
ResultActions actions = mvc.perform(get("/").accept(TestMvcClient.DEFAULT_MEDIA_TYPE)).andExpect(status().isOk());
|
||||
|
||||
for (String rel : expectedRootLinkRels()) {
|
||||
actions.andExpect(client.hasLinkWithRel(rel));
|
||||
actions.andDo(MockMvcResultHandlers.print()).andExpect(client.hasLinkWithRel(rel));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -237,18 +237,18 @@ public class RepositoryEntityControllerIntegrationTests extends AbstractControll
|
||||
public void deletesEntityWithCustomLookupCorrectly() throws Exception {
|
||||
|
||||
Address address = repository.save(new Address());
|
||||
assertThat(repository.findOne(address.id)).isNotNull();
|
||||
assertThat(repository.findById(address.id)).isNotNull();
|
||||
|
||||
RootResourceInformation resourceInformation = getResourceInformation(Address.class);
|
||||
RepositoryInvoker invoker = spy(resourceInformation.getInvoker());
|
||||
doReturn(Optional.of(address)).when(invoker).invokeFindOne("foo");
|
||||
doReturn(Optional.of(address)).when(invoker).invokeFindById("foo");
|
||||
|
||||
RootResourceInformation informationSpy = Mockito.spy(resourceInformation);
|
||||
doReturn(invoker).when(informationSpy).getInvoker();
|
||||
|
||||
controller.deleteItemResource(informationSpy, "foo", ETag.from("0"));
|
||||
|
||||
assertThat(repository.findOne(address.id)).isEmpty();
|
||||
assertThat(repository.findById(address.id)).isEmpty();
|
||||
}
|
||||
|
||||
interface AddressProjection {}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class TestDataPopulator {
|
||||
Author john = new Author("John");
|
||||
Author thomas = new Author("Thomas");
|
||||
|
||||
Iterable<Author> authors = this.authors.save(Arrays.asList(ollie, mark, michael, david, john, thomas));
|
||||
Iterable<Author> authors = this.authors.saveAll(Arrays.asList(ollie, mark, michael, david, john, thomas));
|
||||
|
||||
books.save(new Book("1449323952", "Spring Data", 1000, authors, new Offer(21.21, "EUR")));
|
||||
books.save(new Book("1449323953", "Spring Data (Second Edition)", 2000, authors, new Offer(30.99, "EUR")));
|
||||
@@ -79,6 +79,6 @@ public class TestDataPopulator {
|
||||
jane.addSibling(john);
|
||||
jane.setFather(billyBob);
|
||||
|
||||
people.save(Arrays.asList(john, jane));
|
||||
people.saveAll(Arrays.asList(john, jane));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class Jackson2DatatypeHelperIntegrationTests {
|
||||
|
||||
PersistentEntity<?, ?> entity = entities.getRequiredPersistentEntity(Order.class);
|
||||
PersistentProperty<?> property = entity.getRequiredPersistentProperty("creator");
|
||||
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(orders.findOne(this.order.getId()).orElse(null));
|
||||
PersistentPropertyAccessor accessor = entity.getPropertyAccessor(orders.findById(this.order.getId()).orElse(null));
|
||||
|
||||
assertThat(objectMapper.writeValueAsString(accessor.getProperty(property))).isNotEqualTo("null");
|
||||
}
|
||||
|
||||
@@ -33,5 +33,5 @@ public interface ProfileRepository extends PagingAndSortingRepository<Profile, S
|
||||
long countByType(@Param("type") String type);
|
||||
|
||||
// DATAREST-511
|
||||
Optional<Profile> findById(@Param("id") String id);
|
||||
Optional<Profile> findProfileById(@Param("id") String id);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class MongoWebTests extends CommonWebTests {
|
||||
linkedIn.setPerson(1L);
|
||||
linkedIn.setType("LinkedIn");
|
||||
|
||||
repository.save(Arrays.asList(twitter, linkedIn));
|
||||
repository.saveAll(Arrays.asList(twitter, linkedIn));
|
||||
|
||||
Address address = new Address();
|
||||
address.street = "ETagDoesntMatchExceptionUnitTests";
|
||||
@@ -288,7 +288,7 @@ public class MongoWebTests extends CommonWebTests {
|
||||
|
||||
Profile profile = repository.findAll().iterator().next();
|
||||
|
||||
Link link = client.discoverUnique("profiles", "search", "findById");
|
||||
Link link = client.discoverUnique("profiles", "search", "findProfileById");
|
||||
|
||||
mvc.perform(get(link.expand(profile.getId()).getHref())).//
|
||||
andExpect(status().isOk());
|
||||
@@ -297,7 +297,7 @@ public class MongoWebTests extends CommonWebTests {
|
||||
@Test // DATAREST-517
|
||||
public void returnsNotFoundIfQueryExecutionDoesNotReturnResult() throws Exception {
|
||||
|
||||
Link link = client.discoverUnique("profiles", "search", "findById");
|
||||
Link link = client.discoverUnique("profiles", "search", "findProfileById");
|
||||
|
||||
mvc.perform(get(link.expand("").getHref())).//
|
||||
andExpect(status().isNotFound());
|
||||
@@ -319,7 +319,7 @@ public class MongoWebTests extends CommonWebTests {
|
||||
@Test // DATAREST-835
|
||||
public void exposesETagHeaderForSearchResourceYieldingItemResource() throws Exception {
|
||||
|
||||
Link link = client.discoverUnique("profiles", "search", "findById");
|
||||
Link link = client.discoverUnique("profiles", "search", "findProfileById");
|
||||
|
||||
Profile profile = repository.findAll().iterator().next();
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package org.springframework.data.rest.webmvc.config;
|
||||
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -29,7 +30,6 @@ import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
import org.springframework.data.querydsl.QuerydslRepositoryInvokerAdapter;
|
||||
import org.springframework.data.querydsl.SimpleEntityPathResolver;
|
||||
@@ -47,6 +47,8 @@ import org.springframework.data.rest.tests.mongodb.ReceiptRepository;
|
||||
import org.springframework.data.rest.tests.mongodb.User;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import com.querydsl.core.types.Predicate;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver}.
|
||||
*
|
||||
@@ -60,6 +62,7 @@ public class QuerydslAwareRootResourceInformationHandlerMethodArgumentResolverUn
|
||||
@Mock Repositories repositories;
|
||||
@Mock RepositoryInvokerFactory invokerFactory;
|
||||
@Mock ResourceMetadataHandlerMethodArgumentResolver resourceMetadataResolver;
|
||||
@Mock QuerydslPredicateBuilder builder;
|
||||
|
||||
@Mock RepositoryInvoker invoker;
|
||||
@Mock MethodParameter parameter;
|
||||
@@ -71,12 +74,11 @@ public class QuerydslAwareRootResourceInformationHandlerMethodArgumentResolverUn
|
||||
|
||||
QuerydslBindingsFactory factory = new QuerydslBindingsFactory(SimpleEntityPathResolver.INSTANCE);
|
||||
ReflectionTestUtils.setField(factory, "repositories", Optional.of(repositories));
|
||||
QuerydslPredicateBuilder builder = new QuerydslPredicateBuilder(new DefaultConversionService(),
|
||||
factory.getEntityPathResolver());
|
||||
|
||||
this.resolver = new QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver(repositories, invokerFactory,
|
||||
resourceMetadataResolver, builder, factory);
|
||||
|
||||
when(builder.getPredicate(any(), any(), any())).thenReturn(mock(Predicate.class));
|
||||
when(parameter.hasParameterAnnotation(QuerydslPredicate.class)).thenReturn(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ public interface PreAuthorizedOrderRepository extends CrudRepository<Order, UUID
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')") // <2>
|
||||
@Override
|
||||
void delete(UUID aLong);
|
||||
void deleteById(UUID aLong);
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@Override
|
||||
@@ -38,7 +38,7 @@ public interface PreAuthorizedOrderRepository extends CrudRepository<Order, UUID
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@Override
|
||||
void delete(Iterable<? extends Order> orders);
|
||||
void deleteAll(Iterable<? extends Order> orders);
|
||||
|
||||
@PreAuthorize("hasRole('ROLE_ADMIN')")
|
||||
@Override
|
||||
|
||||
@@ -28,7 +28,7 @@ public interface SecuredPersonRepository extends CrudRepository<Person, UUID> {
|
||||
|
||||
@Secured("ROLE_ADMIN") // <2>
|
||||
@Override
|
||||
void delete(UUID aLong);
|
||||
void deleteById(UUID aLong);
|
||||
|
||||
@Secured("ROLE_ADMIN")
|
||||
@Override
|
||||
@@ -36,7 +36,7 @@ public interface SecuredPersonRepository extends CrudRepository<Person, UUID> {
|
||||
|
||||
@Secured("ROLE_ADMIN")
|
||||
@Override
|
||||
void delete(Iterable<? extends Person> persons);
|
||||
void deleteAll(Iterable<? extends Person> persons);
|
||||
|
||||
@Secured("ROLE_ADMIN")
|
||||
@Override
|
||||
|
||||
@@ -69,7 +69,7 @@ public class SolrWebTests extends CommonWebTests {
|
||||
public void setUp() {
|
||||
|
||||
super.setUp();
|
||||
repo.save(Arrays.asList(PLAYSTATION, GAMEBOY, AMIGA500));
|
||||
repo.saveAll(Arrays.asList(PLAYSTATION, GAMEBOY, AMIGA500));
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
@@ -416,7 +416,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
|
||||
resourceInformation.verifySupportedMethod(HttpMethod.DELETE, ResourceType.ITEM);
|
||||
|
||||
RepositoryInvoker invoker = resourceInformation.getInvoker();
|
||||
Optional<Object> domainObj = invoker.invokeFindOne(id);
|
||||
Optional<Object> domainObj = invoker.invokeFindById(id);
|
||||
|
||||
return domainObj.map(it -> {
|
||||
|
||||
@@ -425,7 +425,7 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
|
||||
eTag.verify(entity, it);
|
||||
|
||||
publisher.publishEvent(new BeforeDeleteEvent(it));
|
||||
invoker.invokeDelete((Serializable) entity.getIdentifierAccessor(it).getIdentifier().orElse(null));
|
||||
invoker.invokeDeleteById((Serializable) entity.getIdentifierAccessor(it).getIdentifier().orElse(null));
|
||||
publisher.publishEvent(new AfterDeleteEvent(it));
|
||||
|
||||
return new ResponseEntity<Object>(HttpStatus.NO_CONTENT);
|
||||
@@ -513,6 +513,6 @@ class RepositoryEntityController extends AbstractRepositoryRestController implem
|
||||
|
||||
resourceInformation.verifySupportedMethod(HttpMethod.GET, ResourceType.ITEM);
|
||||
|
||||
return resourceInformation.getInvoker().invokeFindOne(id);
|
||||
return resourceInformation.getInvoker().invokeFindById(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +397,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
|
||||
RepositoryInvoker invoker = repositoryInvokerFactory.getInvokerFor(type);
|
||||
|
||||
return invoker.invokeFindOne(id);
|
||||
return invoker.invokeFindById(id);
|
||||
}
|
||||
|
||||
private Optional<ResourceSupport> doWithReferencedProperty(RootResourceInformation resourceInformation,
|
||||
@@ -415,7 +415,7 @@ class RepositoryPropertyReferenceController extends AbstractRepositoryRestContro
|
||||
resourceInformation.verifySupportedMethod(method, property);
|
||||
|
||||
RepositoryInvoker invoker = resourceInformation.getInvoker();
|
||||
Optional<Object> domainObj = invoker.invokeFindOne(id);
|
||||
Optional<Object> domainObj = invoker.invokeFindById(id);
|
||||
|
||||
domainObj.orElseThrow(() -> new ResourceNotFoundException());
|
||||
|
||||
|
||||
@@ -74,6 +74,15 @@ public class AlpsJsonHttpMessageConverter extends MappingJackson2HttpMessageConv
|
||||
&& super.canWrite(clazz, mediaType);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.http.converter.AbstractGenericHttpMessageConverter#canWrite(java.lang.reflect.Type, java.lang.Class, org.springframework.http.MediaType)
|
||||
*/
|
||||
@Override
|
||||
public boolean canWrite(Type type, Class<?> clazz, MediaType mediaType) {
|
||||
return canWrite(clazz, mediaType);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.http.converter.json.MappingJackson2HttpMessageConverter#canRead(java.lang.reflect.Type, java.lang.Class, org.springframework.http.MediaType)
|
||||
|
||||
@@ -128,7 +128,7 @@ public class PersistentEntityResourceHandlerMethodArgumentResolver implements Ha
|
||||
|
||||
Optional<Serializable> id = Optional
|
||||
.ofNullable(idResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory));
|
||||
Optional<Object> objectToUpdate = id.flatMap(it -> resourceInformation.getInvoker().invokeFindOne(it));
|
||||
Optional<Object> objectToUpdate = id.flatMap(it -> resourceInformation.getInvoker().invokeFindById(it));
|
||||
|
||||
Object obj = read(resourceInformation, incoming, converter, objectToUpdate);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.data.rest.webmvc.config;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.core.MethodParameter;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
@@ -35,6 +36,7 @@ import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
|
||||
import com.mysema.commons.lang.Pair;
|
||||
import com.querydsl.core.types.Predicate;
|
||||
|
||||
/**
|
||||
@@ -75,7 +77,6 @@ class QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver
|
||||
* @see org.springframework.data.rest.webmvc.config.RootResourceInformationHandlerMethodArgumentResolver#postProcess(org.springframework.data.repository.support.RepositoryInvoker, java.lang.Class, java.util.Map)
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected RepositoryInvoker postProcess(MethodParameter parameter, RepositoryInvoker invoker, Class<?> domainType,
|
||||
Map<String, String[]> parameters) {
|
||||
|
||||
@@ -85,17 +86,27 @@ class QuerydslAwareRootResourceInformationHandlerMethodArgumentResolver
|
||||
|
||||
return repositories.getRepositoryFor(domainType)//
|
||||
.filter(it -> QuerydslPredicateExecutor.class.isInstance(it))//
|
||||
.map(it -> {
|
||||
.map(it -> QuerydslPredicateExecutor.class.cast(it))//
|
||||
.flatMap(it -> getRepositoryAndPredicate(it, domainType, parameters))//
|
||||
.map(it -> getQuerydslAdapter(invoker, it.getFirst(), it.getSecond()))//
|
||||
.orElse(invoker);
|
||||
}
|
||||
|
||||
ClassTypeInformation<?> type = ClassTypeInformation.from(domainType);
|
||||
private Optional<Pair<QuerydslPredicateExecutor<?>, Predicate>> getRepositoryAndPredicate(
|
||||
QuerydslPredicateExecutor<?> repository, Class<?> domainType, Map<String, String[]> parameters) {
|
||||
|
||||
QuerydslBindings bindings = factory.createBindingsFor(type);
|
||||
Predicate predicate = predicateBuilder.getPredicate(type, toMultiValueMap(parameters), bindings);
|
||||
ClassTypeInformation<?> type = ClassTypeInformation.from(domainType);
|
||||
|
||||
return (RepositoryInvoker) new QuerydslRepositoryInvokerAdapter(invoker,
|
||||
(QuerydslPredicateExecutor<Object>) it, predicate);
|
||||
QuerydslBindings bindings = factory.createBindingsFor(type);
|
||||
Predicate predicate = predicateBuilder.getPredicate(type, toMultiValueMap(parameters), bindings);
|
||||
|
||||
}).orElse(invoker);
|
||||
return Optional.ofNullable(predicate).map(it -> Pair.of(repository, it));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static RepositoryInvoker getQuerydslAdapter(RepositoryInvoker invoker,
|
||||
QuerydslPredicateExecutor<?> repository, Predicate predicate) {
|
||||
return new QuerydslRepositoryInvokerAdapter(invoker, (QuerydslPredicateExecutor<Object>) repository, predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -762,7 +762,7 @@ public class PersistentEntityJackson2Module extends SimpleModule {
|
||||
*/
|
||||
@Override
|
||||
public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
|
||||
return invoker.invokeFindOne(p.getValueAsString());
|
||||
return invoker.invokeFindById(p.getValueAsString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,8 +80,8 @@ public class RepositoryPropertyReferenceControllerUnitTests {
|
||||
controller.setApplicationEventPublisher(publisher);
|
||||
|
||||
doReturn(invoker).when(invokerFactory).getInvokerFor(Reference.class);
|
||||
doReturn(Optional.of(new Sample())).when(invoker).invokeFindOne(4711);
|
||||
doReturn(Optional.of(new Reference())).when(invoker).invokeFindOne("some-id");
|
||||
doReturn(Optional.of(new Sample())).when(invoker).invokeFindById(4711);
|
||||
doReturn(Optional.of(new Reference())).when(invoker).invokeFindById("some-id");
|
||||
doReturn(new Sample()).when(invoker).invokeSave(any(Object.class));
|
||||
|
||||
RootResourceInformation information = new RootResourceInformation(metadata, entity, invoker);
|
||||
@@ -90,7 +90,7 @@ public class RepositoryPropertyReferenceControllerUnitTests {
|
||||
controller.createPropertyReference(information, HttpMethod.POST, request, 4711, "references");
|
||||
|
||||
verify(invokerFactory).getInvokerFor(Reference.class);
|
||||
verify(invoker).invokeFindOne("some-id");
|
||||
verify(invoker).invokeFindById("some-id");
|
||||
}
|
||||
|
||||
@RestResource
|
||||
|
||||
Reference in New Issue
Block a user