Spring Data JPA

repository·main·Indexed 25 days ago

https://github.com/spring-projects/spring-data-jpa

A module of the Spring Data family that simplifies the implementation of JPA-based data access layers. It reduces boilerplate code by providing automatic implementations for CRUD operations, dynamic query generation from method names, and support for auditing, pagination, and stored procedure execution via the @Procedure annotation.

Tokens
21.9K
Snippets
58
Records
94
Agent score
77%

What's inside Spring Data JPA

  1. Understand default transactionality in Spring Data JPA

    main

    By default, methods inherited from CrudRepository use the transactional configuration from SimpleJpaRepository.

    • Read operations: The readOnly flag is set to true.
    • Other operations: Configured with a plain @Transactional so that default transaction configuration applies.
    • Transactional fragments: Repository methods backed by transactional repository fragments inherit the transactional attributes from the actual fragment method.
  2. Understand Spring Data JPA Repository Abstraction

    main

    Spring Data JPA provides a repository abstraction designed to significantly reduce the amount of boilerplate code required to implement data access layers for JPA-based persistence stores.

    Before using JPA-specific features, ensure you have a foundational understanding of the core Spring Data repository concepts, such as how repository interfaces are defined and how they interact with the underlying persistence context.

  3. Use Spring Data JPA Snapshots via Maven

    main

    If you need the latest snapshots of the upcoming major version, add the Spring Snapshot repository and use the -SNAPSHOT version suffix in your dependency declaration.

    <dependency>
      <groupId>org.springframework.data</groupId>
      <artifactId>spring-data-jpa</artifactId>
      <version>${version}-SNAPSHOT</version>
    </dependency>
    
    <repository>
      <id>spring-snapshot</id>
      <name>Spring Snapshot Repository</name>
      <url>https://repo.spring.io/snapshot</url>
    </repository>
  4. Activate JPA Auditing via Java configuration

    main

    You can enable auditing by annotating a configuration class with @EnableJpaAuditing. You must still ensure AuditingEntityListener is registered (via orm.xml or @EntityListeners) and that spring-aspects.jar is on the classpath.

    If you have multiple AuditorAware beans in your ApplicationContext, use the auditorAwareRef attribute of @EnableJpaAuditing to select the specific one to use.

    @Configuration
    @EnableJpaAuditing
    class Config {
    
      @Bean
      public AuditorAware<AuditableUser> auditorProvider() {
        return new AuditorAwareImpl();
      }
    }
  5. Execute queries using the Specification Fluent API

    main

    The JpaSpecificationExecutor provides a fluent API via the findBy method to execute queries derived from a Specification or PredicateSpecification. This allows dynamic control over query execution aspects.

    Intermediate methods (to be used within the query function):

    • sortBy(Sort sort): Apply ordering. Repeated calls append sorts.
    • limit(long limit): Limit result count.
    • as(Class<R> type): Specify the type for projection.
    • project(...): Limit query properties.

    Terminal methods (to be used within the query function):

    • first(): Returns Optional<T> for the first result.
    • firstValue(): Returns a nullable result for the first value.
    • one(): Returns Optional<T> for exactly one result; throws IncorrectResultSizeDataAccessException if more than one is found.
    • oneValue(): Returns a nullable result for exactly one value.
    • all(): Returns all results as a List<T>.
    • page(Pageable): Returns a Page<T>.
    • slice(Pageable): Returns a Slice<T>.
    • scroll(ScrollPosition): Returns a Window<T> using scrolling.
    • stream(): Returns a stateful Stream<T> (must be closed).
    • count(): Returns the count of matching entities.
    • exists(): Returns whether any match exists.

    Example: Get a projected Page ordered by lastname:

    Page<CustomerProjection> page = repository.findBy(spec,
        q -> q.as(CustomerProjection.class)
              .page(PageRequest.of(0, 20, Sort.by("lastname")))
    );
  6. Declare annotated vector search methods

    main
    Annotated search methods provide full control over query semantics and do not rely on method name conventions. This approach allows for more complex queries, such as using Similarity normalization to map similarity values to score predicates. If an annotated query does not explicitly define a score, the score value in the returned SearchResult<T> will be zero.
  7. Apply transactions to declared query methods

    main

    Declared query methods (including default methods) do not receive transaction configuration by default. To make them transactional, apply @Transactional to the repository interface or the specific method.

    For read-only queries, it is recommended to set readOnly = true to provide hints to the JDBC driver and allow JPA provider optimizations (e.g., Hibernate setting flush mode to MANUAL to skip dirty checks).

    @Transactional(readOnly = true)
    interface UserRepository extends JpaRepository<User, Long> {
    
    List<User> findByLastname(String lastname);
    
    @Modifying
      @Transactional
      @Query("delete from User u where u.active = false")
      void deleteInactiveUsers();
    }