Skip to content

Spring Data ​

Spring Data helps you access and manipulate data in databases without writing tons of code.

Key Features: ​

  • Repository Abstraction: You define an interface, and Spring Data auto-generates the implementation.
  • Query Methods: Write queries by just naming your methods (like findByUsername()).
  • Support for Many Data Stores:
    • Relational (JPA/Hibernate, JDBC)
    • NoSQL (MongoDB, Neo4j, Redis, Cassandra, etc.)
    • Pagination and Sorting
    • Custom Queries using JPQL, native SQL, or annotations

Repository ​

Data Access Object level. Interface remains constant independent of the DB behind it.

Repository (Marker-Interface) -> CRUDRepository -> PagingAndSortingRepository

Derived Queries ​

Queries generated by Spring Data based on the signature.

Methods only need to be defined in the interface. No implementation is required.

Examples ​

  • findByFirstNameAndLastName(String name, String lastname) -> And queries
  • findByFirstNameOrderByCreated(String name) -> Ordering
  • deleteByName(String name) -> Deletion
  • findByAgeGreaterThan -> Less than, greater than, etc
  • CountBy -> Results as long
  • readBy
  • getBy
  • queryBy
  • findFirst -> returns first entry

AND-OR ​

Any And, Or Keywords

java
findByFirstNameAndLastName

EQUALS-IS-NOT ​

java
List<Session> findBySessionLengthNot(Integer length);

LIKE- NOT LIKE ​

Placeholder: %

java
List<Session> findBySessionNameNotLike(String name);

STARTING/ENDING WITH – CONTAINING ​

java
List<Session> findBySessionNameStartingWith(String name);

LESS THAN – GREATER THAN ​

java
List<Session> findBySessionLengthLessThan(Integer length);

BEFORE – AFTER – BETWEEN ​

For Date/Time-Queries

TRUE – FALSE ​

For boolean fields

java
List<TicketType> findByIncludesWorkshopTrue();

NULL – NOT NULL ​

Null, isNull, notNull, isNotNull

java
List <Speaker> findBySpeakerPhotoNull();

IN – NOT IN ​

java
...in(Collection<Daten>)
java
List <Speaker> findByCompanyIn(List<String> companies);

IGNORE CASE ​

java
List<Speaker> findCompanyIgnoreCase(String company);

ORDER BY ​

java
List<Speaker> findByLastNameOrderByFirstNameAsc(String lastName);

FIRST – TOP – DISTINCT ​

java
findTop5ByFirstName

Paging and Sorting ​

java
Iterable<T> findAll(Sort sort);
Page<T> findAll(Pageable pageable);

Or add paging and sorting as parameters to the derived queries.

java
final Page<Flight> page=flightRepository.findByOrigin("London",PageRequest.of(0,5,Sort.by(Sort.Order.desc("destination"))));

or

java
@Query("select * from Session s where s.sessionName like %:name")
Page<Session> getSessionWithName(@Param("name") String name, Pageable page);

Custom Module ​

Extend the repository with custom implementation

  • Create a new interface
  • Implement the interface
  • Existing interface now also extends the CustomRepository interface
java
public interface DeleteByOriginRepository {
    void deleteByOrigin(String origin);
}

public class DeleteByOriginRepositoryImpl implements DeleteByOriginRepository{
    private final EntityManager entityManager;

    public DeleteByOriginRepositoryImpl(EntityManager entityManager){
        this.entityManager=entityManager;
    }

    @Override
    public void deleteByOrigin(String origin) {
        entityManager.createNativeQuery("DELETE from flight where origin =?").setParameter(1, origin).executeUpdate();
    }
}

Extend existing repository with new functionality

java
public interface FlightRepository extends PagingAndSortingRepository<Flight, Long>, DeleteByOriginRepository{
    List<Flight> findByOrigin(String london);

    List<Flight> findByOriginAndDestination(String london, String paris);

    List<Flight> findByOriginIn(String ... origins);

    List<Flight> findByOriginIgnoreCase(String origin);

    Page<Flight> findByOrigin(String origin, Pageable pageRequest);
}

Transactions ​

@Transactional – Annotation to work within a transaction. Reduces boilerplate code, more stable, DB independent…

Tests ​

Annotate with @SpringBootTest

Spring Data JPA ​

• Extends JPA • Simplifies the data layer • JpaRepositories • Query DSL • Data tier (sorting, paging, etc.) • Optional. Can easily be bypassed if necessary

Configuration ​

Pom.xml

xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- Dependency for Postgres JDBC driver -->
<dependency>
   <groupId>org.postgresql</groupId>
   <artifactId>postgresql</artifactId>
   <scope>runtime</scope>
</dependency>
properties
Application.properties
spring.datasource.url=jdbc:postgresql:conference_app
spring.datasource.username=
spring.datasource.password=
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none

spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
spring.jpa.show-sql=true

Repository ​

java
public interface SpeakerJpaRepository extends JpaRepository<Speaker,Long> {
}

Query-Annotation ​

For custom queries. Add method with @Query annotation to repository.

java
@Query("Select tp from TicketPrice tp where tp.basePrice < ?1 "+
        "and tp.ticketType.includesWorkshop = true"
        )
List<TicketPrice> getTicketsUnderPriceWithWorkshops(BigDecimal maxPrice);

?1 First parameter is replaced with parameter of the method.

Named Parameter ​

Instead of numbered parameters, parameter names can be used.

java
@Query("Select tp from TicketPrice tp where tp.basePrice < :maxprice "+
        "and tp.ticketType.includesWorkshop = true"
        )
List<TicketPrice> getTicketsUnderPriceWithWorkshops(@Param(“maxprice”) BigDecimal maxPrice);

Enhanced JPQL Syntax ​

“… where s.sessionName like %?1” Platzhalter ‘%’ kann hinzugefügt werden

Native SQL Query ​

java
@Query(value=“select \* from sessions s where s.session_name= ?0”, nativeQuery = true)
List<Session> getSessionsWithName(String name);

Modifiable Queries ​

java
@Modifying
@Query("update Session s set s.sessionName = ?1")
int updateSessionName(String name);

NamedQueries ​

Named Queries are predefined JPQL (Java Persistence Query Language) queries and are validated at the start of the app They are located on the entity, repository or as named attribute by the query annotation

java
@Entity
@NamedQuery(
    name = "User.findByEmail",
    query = "SELECT u FROM User u WHERE u.email = :email"
)
public class User

NamedNativeQuery ​

java
@Entity
@NamedNativeQuery(
    name = "User.findByEmail",
    query = "SELECT * FROM users WHERE email = ?",
    resultClass = User.class
)
public class User

Query priority ​

  1. @Query-Annotation
  2. Named/NativeNamed-Queries
  3. Query-DSL Naming

Auditing ​

Annotation of entity properties

  • @CreatedBy
  • @LastModifiedBy
  • @CreatedDate (automatically defined)
  • @LastModifiedDate (automatically defined)

Locking ​

java
@Version-Annotation in Entity
@Version
private int version

@Lock(LockModeType.PESSIMISIC_WRITE)
List<Model> findByAttributeName(String name)

Contact: M_Bergmann AT gmx.at