RepositoryRestConfiguration now defaults the LinkRelationProvider instance to a delegating one considering both AnnotationLinkRelationProvider and EvoLinkRelationProvider so that @Relation annotations on entity types.
Moved off Spring Framework deprecations for HttpMessageNotReadableException. This required some rearrangements of method signatures for types (hopefully) exclusively used by internal abstractions (some public, but not very friendly for user extension in the first place).
Switched to consistent use of Pageable.unpaged() instead of null. Switched to the use of new factory methods in Spring HATEOAS. Some Java 8 based improvements in request handling to simplify the implementation code. Deprecation of code that got obsolete due to the use of the factory methods.
Moved off some deprecations in Jackson APIs.
Removed a couple of unused imports. General avoidance of common warnings. Suppression where needed. Removed dead code in configuration.
Previously the backend identifier derived from the URI was set as identifier on the object to be created in a PUT request. However, in case a custom entity lookup is used, this is not the identifier but an arbitrary property pointed to through user defined code, mostly a method reference.
We now use the newly introduced MethodInvocationRecorder API in Spring Data Commons to be able to obtain the property that is supposed to be used and set that to the value calculated. This requires the entity type for which the custom lookup is configured to be non-final as the invocation recording is build on top of proxies.
Related tickets: DATACMNS-1449.
We now properly only answer PersistentEntitiesResourceMappings.hasMappingsFor(…) with true if we find a non-null value in the cache. Previously, even a failed attempt to create some ResourceMapping would've caused ….hasMappingsFor(…) to indicate it PersistentEntitiesResourceMappings contains a mapping.
This lead to downstream NullPointerExceptions as ….getMetadataFor(…) was accessed without a null guard after ….hasMappingFor(…) returned true.
DomainObjectReader now aborts the recursive merges in case it encounters an entity that's described as @Immutable (just introduced in Spring Data Commons).
Fixed some generics and removed DomainObjectMerger as it's unused.
Related ticket: DATACMNS-1322.
We now provide and configure a converter for String to LdapName conversion so Spring Data LDAP can be used with Spring Data REST without further configuration.
Original pull request: #290.
ExposureConfiguration exposes methods to register AggregateResourceHttpMethodsFilter and AssociationResourceHttpMethodsFilter (both applied by type or globally) to customize the supported HTTP methods by collection, item and association resources. It also provides shortcuts for common use cases like disabling PUT for item resources etc.
The default exposure of repository methods is now controlled via RepositoryRestConfiguration.setExposeRepositoryMethodsByDefault(…). That allows us to remove the additional API from RepositoryDetectionStrategy as the mere detection is an orthogonal topic.
Also added RepositoryRestConfiguration.disableDefaultExposure() to set the RepositoryDetectionStategy to ANNOTATED and disables default method exposure in one go. That can be exposed via a Spring Boot configuration property downstream.
Moved the flag to decide whether to expose repository methods by default to the RepositoryDetectionStrategy interface, so that it can be directly accessed and the test on the particular enum value is not needed anymore and thus also not duplicated into different parts of the codebase.
Added more tests to actually verify behavior on CrudMethodsSupportedHttpMethods. DefaultExposureAwareCrudMethods uses @RequiredArgumentConstructor again.
The field value lookup in ValidationErrors previously threw a NotReadablePropertyException in case a property value was null as we incorrectly piped the null value into an Optional in turn. We now eagerly reject the property if we can't find a PersistentProperty in the metamodel to avoid this.
We now expose the constructor that takes a RelProvider in RepositoryResourceMappings so that clients can tweak the default relation names. Changed the order of constructor parameters of (previously) non-public constructors for consistency.
The RelProvider to be used with the mappings can now be configured via RepositoryRestConfiguration and defaults to the EvoInflector based one.
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.
In case PersistentEntities exposes a managed type whose raw type currently doesn't have a PersistentEntity registered, the constructor of UriToEntityConverter ran into a NullPointerException.
We now explicitly check for null and skip those types.
Filed DATAREST-1021 for further improvements in the 3.0 time frame.
We now resolve the handler method argument type of an annotated repository event handler against the concrete handler type to make sure generics are resolved properly.
We now make sure that an @Order annotation on annotated event handler methods are considered and the methods are invoked in the defined order.
Non-annotation-based event handlers don't suffer from the same problem as they're ApplicationListener instances directly so that the container will enforce the correct ordering in case @Order is used or Ordered is implemented.
Some cleanup in EventHandlerMethod.
Original pull request: #248.
Fixed broken equals(…) in ProjectionDefinition. Switched to iterating over Map's entry set instead of the keys. Made UriAwareHttpServletRequest static.
Removed RepositoryRestConfiguration.addCorsMapping(…) as we currently don't have any other shortcut methods for configuration like this.
Tweaked the setup of (now Repository)CorsConfigurationAccessor to be created earlier so that we avoid recreation for every lookup. Introduced a NoOpStringValueResolver to be used by default so that we don't need to deal with the case of the resolver being null at the end of the call chain. Replaced constructor of RepositoryCorsConfigurationAccessor with corresponding Lombok annotation.
Updated reference documentation accordingly.
Original pull request: #233.
We now support CORS configuration mechanisms introduced in Spring 4.2. CORS can be configured on multiple levels: Repository interface, Repository REST controller and global level. Spring Data REST CORS configuration is isolated so Spring Web MVC'S CORS configuration does not apply to Spring Data REST resources.
Multiple configuration sources are merged so different aspects of CORS can be configured in separate locations.
@CrossOrigin
interface PersonRepository extends CrudRepository<Person, Long> {}
@RepositoryRestController
@RequestMapping("/person")
public class PersonController {
@CrossOrigin(maxAge = 3600)
@RequestMapping(method = RequestMethod.GET, "/xml/{id}", produces = MediaType.APPLICATION_XML_VALUE)
public Person retrieve(@PathVariable Long id) {
// ...
}
}
@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.addCorsMapping("/person/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
}
Previously our support for the HTTP DELETE method on item resources was requiring a repository's findOne(…) method to be available and exposed. However, the latter might not be desirable as the support of GET and HEAD requests for item resources depends on that.
We now changed that to only checking that a findOne(…) method is declared on the repository as the implementation of RepositoryEntityController.deleteItemResource(…) requires it to be present to be able to trigger the events that intercept deletes for a particular type.
We now correctly handle nested values by manually traversing the potentially nested property path, creating a PropertyAccessor for each nesting step considering the property access settings defined in the mapping metadata.
Changed the implementation of ValidationErrors to be based on AbstractBeanPropertyBindingResult to consider the nesting implemented in superclasses and using a PersistentPropertyAccessor to lookup the property values.
ValidatingRepositoryEventListener now uses this implementation if a PersistentEntity can be obtained for the type under consideration, falling back to a DirectFieldBindingResult otherwise.
Upgraded to JSONPath 1.1.0 as 0.9 is not supported with Spring 4.2 anymore. Tweaked integration tests due to changed semantics and internals of JSONPath >= 1.0.
Extracted store specific tests into separate test modules to prevent classpath overlap between projects. Those tests are now executed in an "it" build profile to prevent the tests being packaged for distribution on release.
Use Map-based repositories and mapping contexts for test in the Core and WebMvc module.
Slightly changed the configuration API for lookup types on RepositoryRestConfiguration.
Related ticket: DATAREST-776.
UriToEntityDeserializer now uses the RepositoryInvokerFactory to resolve entity instances directly to make sure potentially registered EntityLookup instances are considered for the lookup.
Spring Data REST now exposes an EntityLookup interface that allows to customize the property of an entity that shall be used to create item resource URIs. By default this mechanism uses the backend identifier and uses the repository's findOne(…) method.
The EntityLookup now exposes one method to return the property value to be used for URI generation as well as one method to obtain the entity instance from the very same raw identifier value. The EntityLookups are registered with both the SelfLinkProvider (for link creation) and the RepositoryInvoker (to obtain the entity instance).
RepositoryRestConfiguration now exposes a setRepositoryDetectionStrategy(…) to define which repositories should be detected for exposure by default. The default value for that will consider the repository interfaces visibility but also take the exported flag of @(Repository)RestResource into account. See all other options in RepositoryDetectionStrategies.
Tweaked the auto-registration of excerpt projections to avoid a circular dependency between configuration and resource mappings and moved it onto a BeanPostProcessor implementation.
We now explicitly drop parameters of type Pageable and Sort from being exposed as search resource parameters as they're added via the UriComponentsContributors anyway. This prevents "pageable" from showing up as parameter on Java 8 code compiled with -parameters. The latter adds naming information for the Pageable parameter and caused it showing up as is despite the fact that the UriComponentsContributor for Pageables exposes a dedicated syntax.