Closed hohwille closed 3 years ago
Created a feature branch of the reference project with Spring Data Integration, where I replaced the DAOs with the repository concept of Spring Data. Tested it in both native and normal JVM mode. Link to the Quarkus Spring Data guide: https://quarkus.io/guides/spring-data-jpa
To implement a repository the interface has to extend one of the following Spring Data repositories (see the example):
These Spring Data Repositories provide some basic implementations for accessing data. For example, the CrudRepository
interface provides methods for returning all instances of a type (findAll
) or returning an instance by its ID (findById
).
Methods of repository interfaces that follow Spring Data conventions are implemented automatically. This means that you do not have to write code for them. Examples:
findByName
(if there is a name attribute)findByNameOrderByAge
(if there is a name and a age attribute)You can customize your repository to add additional functionality or override the default implementations by using repository fragments: https://github.com/devonfw-forge/devonfw-microservices/blob/feature/spring_data/reference-project/src/main/java/com/devonfw/demoquarkus/domain/repo/AnimalFragmentImpl.java
@Query annotations
The Quarkus Spring Data extension supports the definition of static PSQL queries with the @Query annotation (see example here).
Native and named queries are not supported using @Query annotation. You will recieve something like Build step io.quarkus.spring.data.deployment.SpringDataJPAProcessor#build threw an exception: java.lang.IllegalArgumentException: Attribute nativeQuery of @Query is currently not supported.
Criteria API Quarkus supports the use of the Criteria API in both native and JVM mode to define dynamic queries (see example here).
QueryDSL QuerySQL, contrary to what is claimed in the Quarkus Spring Data guide, works in both native and JVM mode to define dynamic queries (see example here).
Pagination Quarkus Spring Data offers paging support. Unfortunately, this only seems to be fully functional in JVM mode. In JVM mode the content and page information is returned, but in native mode only the content is returned.
JVM mode:
{
"content": [
{
"id": 1,
"name": "...",
...
},
...
],
"pageable": "...",
"last": ...,
"totalPages": ...,
"totalElements": ...,
"size": ...,
"number": ...,
"sort": {
"sorted": ...,
"unsorted": ...,
"empty": ...
},
"first": ...,
"numberOfElements": ...,
"empty": ...
}
Native mode:
{
"totalPages": ...
"totalElements": ...
}
@GuentherJulian thank you for your testing and feedback. This is exactly what we need and what I requested with this issue. Great work 👍
So the great news is that it is working and supported in general not only in JVM mode but also in native image. To summarize the limitations (at least in native image):
@Query(native=true, ...)
) currently not supported.Is that sufficient for a real-world project production usage? Yes and no! Yes as it is what you need to get started. But no as paging support is mandatory and native queries are important for performance tuning options in real world scenarios. So IMHO we should get in touch with the dev teams and see if we can get some details about the status:
I think this is all an excellent starting point to create documentation about spring-data support as a guide. The "status" (incomplete features / limitations) should be a separate section. Ideally with our approach to get in touch we should try to figure out according issues in the projects that indicate the story for the lacking feature and makes the implementation status transparent. Then we can simply link to such issue. This allows everybody to track the status even if our documentation is not updated fast enough and also gives developers the chance to connect or even contribute to make it happen.
One further request: It is best practice to use named parameters instead of indexed parameters:
https://github.com/devonfw-forge/devonfw-microservices/blob/d9bc758fd9c9076a06fea5abf3f3851d451c597f/reference-project/src/main/java/com/devonfw/demoquarkus/domain/repo/AnimalRepository.java#L11
So instead of ?1
use :name
and annotate parameter with @Param
. This is especially benefitial when using multiple parameters or especially when the same parameter is used multiple times what is all a mess with indexed parameters. Also indexed parameters always cause confusion and errors as they are 1-based while in development typically indexes are 0-based.
See also the devon4j guide: https://github.com/devonfw/devon4j/blob/master/documentation/guide-repository.asciidoc#example
One further request: It is best practice to use named parameters instead of indexed parameters: https://github.com/devonfw-forge/devonfw-microservices/blob/d9bc758fd9c9076a06fea5abf3f3851d451c597f/reference-project/src/main/java/com/devonfw/demoquarkus/domain/repo/AnimalRepository.java#L11
So instead of
?1
use:name
and annotate parameter with@Param
. This is especially benefitial when using multiple parameters or especially when the same parameter is used multiple times what is all a mess with indexed parameters. Also indexed parameters always cause confusion and errors as they are 1-based while in development typically indexes are 0-based. See also the devon4j guide: https://github.com/devonfw/devon4j/blob/master/documentation/guide-repository.asciidoc#example
Changed it to named parameter
Evalutation is done. Documentation will be created with this task https://github.com/devonfw/devon4quarkus/issues/19
Rechecked the Paging support:
Using the Page<T>
interface (Page documention) as the return type in the rest service, the response in native mode would look like the following:
{
"totalPages": ...
"totalElements": ...
}
In JVM mode all page information is returned, but in native mode only the totalPages
and totalElements
properties can be derived from the interface.
To make it work in native mode, PageImpl<T>
has to be used as the return type. Then the responses in JVM and native mode are the same.
Conclusion: Paging is supported in both native and JVM mode
Conclusion: Paging is supported in both native and JVM mode
Great to hear that.
For native queries I created issue #45 as this issue is already closed.
As a user of devon4j I want to use spring-data-jpa in my quarkus app. Within this story, you should evaluate using spring-data-jpa in a quarkus app.
IMHO it would make sense to create a feature branch from our sample app and port it to spring-data-jpa replacing DAOs (https://github.com/devonfw-forge/devonfw-microservices/blob/main/reference-project/src/main/java/com/devonfw/demoquarkus/domain/dao/AnimalDAO.java) with Repositories.
devon4j documentation of repositories with sample code: https://github.com/devonfw/devon4j/blob/master/documentation/guide-repository.asciidoc#repository
For the record: This is the issue where and why we introduced spring-data in oasp4j (pre-decessor of devon4j): https://github.com/oasp/oasp4j/issues/626