[Spring](EN) Methods for retrieving the first entity in Spring Data JPA


Environment and Prerequisite

  • Java


Method

There are various methods and here I introduce two methods with examples. The post was written after searching inability of using LIMIT 1 in JPQL.

  1. Using JPA Query Methods
  2. Using Pageable


Usage and Example

build.gradle

  • Below build.gradle can be different per project setting.
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.1.5'
	id 'io.spring.dependency-management' version '1.1.3'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	sourceCompatibility = '21'
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	implementation 'org.springframework.boot:spring-boot-starter-security'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	compileOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'com.h2database:h2'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testImplementation 'org.springframework.security:spring-security-test'
	testImplementation 'org.junit.jupiter:junit-jupiter'
	testImplementation 'org.junit.jupiter:junit-jupiter-api'
	testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

tasks.named('bootBuildImage') {
	builder = 'paketobuildpacks/builder-jammy-base:latest'
}

tasks.named('test') {
	useJUnitPlatform()
}

UserEntity

  • Example Entity
package com.example.practice.entity;

import jakarta.persistence.*;
import lombok.*;


@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "email")})
public class UserEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    @Column(nullable = false)
    private String username;

    @Column(nullable = false)
    private String gender;

    @Column(nullable = false)
    private String type;

    @Column(nullable = false)
    private String email;

    @Column(nullable = false)
    private String password;
}

UserRepository

  1. Using JPA Query Methods
    • Create method name according to naming rule.
    • Naming rule can be easily found in official document or below example.
  2. Using Pageable
    • An example uses @Query and returns a List and Pageable is passed to method at the end.
    • The usage can be seen in the test below.
package com.example.practice.repository;

import com.example.practice.entity.UserEntity;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {
    // 1. Using JPA Query Methods
    UserEntity findFirstByGenderAndTypeOrderByIdDesc(String gender, String type);

    // 2. Using Pageable
    @Query("SELECT u FROM UserEntity u WHERE u.gender = :gender AND u.type = :type ORDER BY u.id DESC")
    List<UserEntity> findFirstByGenderAndTypeOrderByIdDescUsingPageable(@Param("gender") String gender, @Param("type") String type, Pageable pageable);
}

UserRepositoryTest

  1. Using JPA Query Methods
    • Call the method as shown in below.
  2. Using Pageable
    • Pass ```PageRequest.of(0, 1)``.
    • PageRequest.of(0, 1): Configuring to retrieve one result on the first page
package com.example.practice.repository;

import com.example.practice.entity.UserEntity;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.util.Arrays;
import java.util.List;

@ExtendWith(SpringExtension.class)
@DataJpaTest
class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void findFirstByGenderAndTypeOrderByNameDescTest() {

        List<UserEntity> userEntities = Arrays.asList(
                UserEntity.builder().
                        email("test1@test.com")
                        .username("testUsername1")
                        .password("testPassword1")
                        .gender("male")
                        .type("A")
                        .build(),
                UserEntity.builder()
                        .email("test2@test.com")
                        .username("testUsername2")
                        .password("testPassword2")
                        .gender("female")
                        .type("A")
                        .build(),
                UserEntity.builder()
                        .email("test3@test.com")
                        .username("testUsername3")
                        .password("testPassword3")
                        .gender("male")
                        .type("A")
                        .build(),
                UserEntity.builder()
                        .email("test4@test.com")
                        .username("testUsername4")
                        .password("testPassword4")
                        .gender("male")
                        .type("B")
                        .build(),
                UserEntity.builder()
                        .email("test5@test.com")
                        .username("testUsername5")
                        .password("testPassword5")
                        .gender("female")
                        .type("A")
                        .build()
        );
        userRepository.saveAll(userEntities);

        // 1. Using JPA Query Methods
        UserEntity resultUser = userRepository.findFirstByGenderAndTypeOrderByIdDesc("male", "A");
        Assertions.assertEquals("test3@test.com", resultUser.getEmail());

        // 2. Using Pageable
        List<UserEntity> resultUsers = userRepository.findFirstByGenderAndTypeOrderByIdDescUsingPageable("male", "A", PageRequest.of(0, 1));
        Assertions.assertEquals("test3@test.com", resultUsers.getFirst().getEmail());
    }
}


Reference