Skip to content

Instantly share code, notes, and snippets.

@thekalinga
Last active March 3, 2019 15:18
Show Gist options
  • Save thekalinga/a1921c7f8caae32666ef3927489b026e to your computer and use it in GitHub Desktop.
Save thekalinga/a1921c7f8caae32666ef3927489b026e to your computer and use it in GitHub Desktop.
Spring Data in a nutshell

WIP

  • Either extend your interface from CrudRepository<T, ID> (or more specific variant of it, if the classpath contains repositories for multiple types of data sources say JpaRepository<T, ID>, MongoRepository<T, ID>)
  • (or) copy paste selective methods from CrudRepository/JpaRepository interface and annotate your interface with @RepositoryDefinition(domainClass = T.class, idClass = Id.class). With this your repository interface would be quite clean
  • @EnableJpaRepositories (+ its persistence specific variants) at the @Configuration class level
  • Expects the transaction manager to be named transactionManager & entityManagerFactory to be named entityManagerFactory by default. If not, we have to explicitly specify the actual names
  • For all default method, you can find implementation in SimpleJpaRepository, which is internally annotated with @Repository (gives exception translation) & @Transactional(readOnly = true) for transactional guarantee

Queries

  • findBy, findAllBy, findByFirstname, findAllByFirstnameLike e.t.c
  • All of the variants can be found org.springframework.data.repository.query.parser.PartTree. This class is responsible for parse method name & build a query tree that can be used to translate to underlying JPQL/SQL query
  • org.springframework.data.repository.query.parser.PartTree.Subject has additional variations that can be specified
  • Navigation JpaRepositoriesAutoConfiguration -> JpaRepositoryFactoryBean -> JpaRepositoryFactory (#createRepositoryFactory) -> JpaQueryLookupStrategy (#getQueryLookupStrategy) -> CreateQueryLookupStrategy (#create) -> PartTreeJpaQuery (#resolveQuery) -> PartTree

Operators

Pagination

  • TODO: explciit count query

DTO binding

Writing custom queries

  • Annotate method with @Query
    • For parameters, use index based binding ?1 (param index starts with 1)
    • Or based on name by using @Param("paramName")
    • or using SPEL ?#{[0]} - spel expressions params are 0 index based
  • Like queries - Place % symbol before or after or in both places dependening on the need. For performance reasons only use prefix based searches, else database does full table scan
    • from Entity e where e.param like :paramName%
    • from Entity e where e.param like ?1%
  • SPEL support
    • ?#{...} specify any expression spring supports inside the braces
    • Default objects are supplied using EvaluationContextExtension. For e.g, Refer to SecurityEvaluationContextExtension that sets SecurityExpressionRoot as one of the root object which provides authentication, principal and other methods like hasRole(..), e.t.c. This requires spring-security-data artifact in addition to spring data & spring security
    • You can do something like @Query("select u from User u where u.emailAddress = ?#{principal.emailAddress}")
    • Query params can be accessed using #paramName format
    • @Query("select u from User u where u.firstname = :#{#firstname}") to access method parameter with name firstname. This does not require method parameter to be annotated with @Param, as this is pure SPEL magic & spring data has nothing to do with it
  • Inside the query we can either write ``

Extending Repository with custom implementations via *RepositoryExtn

For examples, look at https://github.com/spring-projects/spring-data-jpa/blob/master/src/test/java/org/springframework/data/jpa/repository/sample/UserRepository.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment