Skip to content

Commit

Permalink
DATACMNS-751 - Added newly introduced features to the reference docum…
Browse files Browse the repository at this point in the history
…entation.

Added sections to the reference documentation to elaborate on the newly introduced web integration for Querydsl.

Added documentation for Future<T> return types.

Corrected the closing tag for dependency for Spring Data Commons section on dependencies. Fix broken links to Spring Framework reference documentation. Update build requirements in readme.

Original Pull Request: #137
  • Loading branch information
christophstrobl authored and odrotbohm committed Aug 19, 2015
1 parent cc2696f commit ed64dd1
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 5 deletions.
6 changes: 3 additions & 3 deletions readme.md
Expand Up @@ -17,7 +17,7 @@
### Prerequisites

- Maven 3
- Java 7 (the project produces Java 6 compatible bytecode but partially integrates with Java 7)
- Java 8 (the project produces Java 6 compatible bytecode but partially integrates with Java 8)

```
$ git clone https://github.com/spring-projects/spring-data-commons.git
Expand All @@ -29,15 +29,15 @@ $ mvn clean install

This README as well as the [reference documentation](http://docs.spring.io/spring-data/data-commons/docs/current/reference/html/) are the best places to start learning about Spring Data Commons.

The main project [website](http://www.springsource.org/spring-data) contains links to basic project information such as source code, JavaDocs, Issue tracking, etc.
The main project [website](http://projects.spring.io/spring-data/) contains links to basic project information such as source code, JavaDocs, Issue tracking, etc.

For more detailed questions, please refer to [spring-data on stackoverflow](http://stackoverflow.com/questions/tagged/spring-data). If you are new to Spring as well as to Spring Data, look for information about [Spring projects](https://spring.io/projects).

## Contributing to Spring Data Commons

Here are some ways for you to get involved in the community:

* Create [JIRA](https://jira.springsource.org/browse/DATACMNS) tickets for bugs and new features and comment and vote on the ones that you are interested in.
* Create [JIRA](https://jira.spring.io/browse/DATACMNS) tickets for bugs and new features and comment and vote on the ones that you are interested in.
* Github is for social coding: if you want to write code, we encourage contributions through pull requests from [forks of this repository](http://help.github.com/forking/). If you want to contribute code this way, please reference a JIRA ticket as well covering the specific issue you are addressing.
* Watch for upcoming articles on Spring by [subscribing](https://spring.io/blog.atom) to springframework.org

Expand Down
2 changes: 1 addition & 1 deletion src/main/asciidoc/dependencies.adoc
Expand Up @@ -16,7 +16,7 @@ Due to different inception dates of individual Spring Data modules, most of them
<scope>import</scope>
<type>pom</type>
</dependency>
<dependencies>
</dependencies>
</dependencyManagement>
----
====
Expand Down
107 changes: 106 additions & 1 deletion src/main/asciidoc/repositories.adoc
@@ -1,3 +1,6 @@
:spring-framework-docs: http://docs.spring.io/spring/docs/current/spring-framework-reference/html


[[repositories]]
= Working with Spring Data Repositories

Expand Down Expand Up @@ -276,7 +279,7 @@ To resolve this ambiguity you can use `_` inside your method name to manually de
List<Person> findByAddress_ZipCode(ZipCode zipCode);
----

As we treat underscore as a reserved character we stongly advise to follow standard Java naming conventions (i.e. *not* using underscores in property names but camel case instead).
As we treat underscore as a reserved character we strongly advise to follow standard Java naming conventions (i.e. *not* using underscores in property names but camel case instead).

[[repositories.special-parameters]]
=== Special parameter handling
Expand Down Expand Up @@ -363,6 +366,28 @@ try (Stream<User> stream = repository.findAllByCustomQueryAndStream()) {
====
NOTE: Not all Spring Data modules currently support `Stream<T>` as a return type.

[[repositories.query-async]]
=== Async query results

Repository queries can be executed asynchronously using link:{spring-framework-docs}#scheduling[Spring's asynchronous method execution capability]. This means the method will return immediately upon invocation and the actual query execution will occur in a task that has been submitted to a Spring TaskExecutor.

====
[source, java]
----
@Async
Future<User> findByFirstname(String firstname); <1>
@Async
CompletableFuture<User> findOneByFirstname(String firstname); <2>
@Async
ListenableFuture<User> findOneByLastname(String lastname); <3>
----
<1> Use `java.util.concurrent.Future` as return type.
<2> Use a Java 8 `java.util.concurrent.CompletableFuture` as return type.
<3> Use a `org.springframework.util.concurrent.ListenableFuture` as return type.
====

[[repositories.create-instances]]
== Creating repository instances
In this section you create instances and bean definitions for the repository interfaces defined. One way to do so is using the Spring namespace that is shipped with each Spring Data module that supports the repository mechanism although we generally recommend to use the Java-Config style configuration.
Expand Down Expand Up @@ -764,6 +789,86 @@ Assume we have 30 Person instances in the database. You can now trigger a reques

You see that the assembler produced the correct URI and also picks up the default configuration present to resolve the parameters into a `Pageable` for an upcoming request. This means, if you change that configuration, the links will automatically adhere to the change. By default the assembler points to the controller method it was invoked in but that can be customized by handing in a custom `Link` to be used as base to build the pagination links to overloads of the `PagedResourcesAssembler.toResource(…)` method.

[[core.web.type-safe]]
==== QueryDSL web support

For those stores having http://www.querydsl.com/[QueryDSL] integration it is possible to derive queries from the attributes contained in a `Request` query string.

This means that given the `User` object from previous samples a query string

[source,text]
----
?firstname=Dave&lastname=Matthews
----

can be resolved to

[source,text]
----
QUser.user.firstname.eq("Dave").and(QUser.user.lastname.eq("Matthews"))
----

using the `QuerydslPredicateArgumentResolver`.

NOTE: The feature will be automatically enabled along `@EnableSpringDataWebSupport` when Querydsl is found on the classpath.

Adding a `@QuerydslPredicate` to the method signature will provide a ready to use `Predicate` which can be executed via the `QueryDslPredicateExecutor`.

TIP: Type information is typically resolved from the methods return type. Since those information does not necessarily match the domain type it might be a good idea to use the `root` attribute of `QuerydslPredicate`.

====
[source,java]
----
@Controller
class UserController {
@Autowired UserRepository repository;
@RequestMapping(value = "/", method = RequestMethod.GET)
String index(Model model, @QuerydslPredicate(root = User.class) Predicate predicate, <1>
Pageable pageable, @RequestParam MultiValueMap<String, String> parameters) {
model.addAttribute("users", repository.findAll(predicate, pageable));
return "index";
}
}
----
<1> Resolve query string arguments to matching `Predicate` for `User`.
====

The default binding is as follows:

* `Object` on simple properties as `eq`.
* `Object` on collection like properties as `contains`.
* `Collection` on simple properties as `in`.

Those bindings can be customized via the `bindings` attribute of `@QuerydslPredicate` or by making use of Java 8 `default methods` adding the `QuerydslBinderCustomizer` to the repository interface.

====
[source,java]
----
interface UserRepository extends CrudRepository<User, String>,
QueryDslPredicateExecutor<User>, <1>
QuerydslBinderCustomizer<QUser> { <2>
@Override
default public void customize(QuerydslBindings bindings, QUser user) {
bindings.bind(user.username).first((path, value) -> path.contains(value)) <3>
bindings.bind(String.class)
.first((StringPath path, String value) -> path.containsIgnoreCase(value)); <4>
bindings.excluding(user.password); <5>
}
}
----
<1> `QueryDslPredicateExecutor` provides access to specific finder methods for `Predicate`.
<2> `QuerydslBinderCustomizer` defined on the repository interface will be automatically picked up and shortcuts `@QuerydslPredicate(bindings=...)`.
<3> Define the binding for the `username` property to be a simple contains binding.
<4> Define the default binding for `String` properies to be a case insensitive contains match.
<5> Exclude the _password_ property from `Predicate` resolution.
====

[[core.repository-populators]]
=== Repository populators
If you work with the Spring JDBC module, you probably are familiar with the support to populate a `DataSource` using SQL scripts. A similar abstraction is available on the repositories level, although it does not use SQL as the data definition language because it must be store-independent. Thus the populators support XML (through Spring's OXM abstraction) and JSON (through Jackson) to define data with which to populate the repositories.
Expand Down
Expand Up @@ -20,6 +20,9 @@ NOTE: Geospatial types like (`GeoResult`, `GeoResults`, `GeoPage`) are only avai
|`List<T>`|A `List`.
|`Optional<T>`|A Java 8 or Guava `Optional`. Expects the query method to return one result at most. In case no result is found `Optional.empty()`/`Optional.absent()` is returned. More than one result will trigger an `IncorrectResultSizeDataAccessException`.
|`Stream<T>`|A Java 8 `Stream`.
|`Future<T>`|A `Future`. Expects method to be annotated with `@Async` and requires Spring's asynchronous method execution capability enabled.
|`CompletableFuture<T>`|A Java 8 `CompletableFuture`. Expects method to be annotated with `@Async` and requires Spring's asynchronous method execution capability enabled.
|`ListenableFuture`|A `org.springframework.util.concurrent.ListenableFuture`. Expects method to be annotated with `@Async` and requires Spring's asynchronous method execution capability enabled.
|`Slice`|A sized chunk of data with information whether there is more data available. Requires a `Pageable` method parameter.
|`Page<T>`|A `Slice` with additional information, e.g. the total number of results. Requires a `Pageable` method parameter.
|`GeoResult<T>`|A result entry with additional information, e.g. distance to a reference location.
Expand Down

0 comments on commit ed64dd1

Please sign in to comment.