網頁

2020/11/3

Spring Data JPA Repository 方法回傳null處理

Spring Data JPA Repository方法回傳結果為空時,可以回傳null物件或以Optional包裝回傳。

注意在Spring Data JPA 2.0後才支援回傳Java 8的Optional

例如entity類Employee的Repository EmployeeRepository繼承JpaRepository的回傳結果可以是EmployeeOptional<Employee>

EmployeeRepository

package com.abc.demo.repository;

import com.abc.demo.entity.Employee;
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.Optional;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

    Employee findByName(String name); // 回傳Employee,若查詢結果為空則內容為null

    @Query("select e from Employee e where e.name = :name")
    Optional<Employee> findByNameJPQL(@Param("name") String name); // 回傳Optional包裝的Employee

}

EMPLOYEE現有ㄧ資料如下。

INSERT INTO EMPLOYEE (ID, NAME, AGE) VALUES (1, 'John', 22);

測試程式。

EmployeeRepositoryTests

package com.abc.demo.repository;

import com.abc.demo.entity.Employee;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Optional;

@SpringBootTest
class EmployeeRepositoryTests {

    @Autowired
    private EmployeeRepository employeeRepository;

    @Test
    void findByName_returnNull() {
        Employee employee = employeeRepository.findByName("Jack");
        System.out.println(employee); // null

        Assertions.assertNull(employee);
    }

    @Test
    void findByName_returnOptionalIsEmpty() {
        Optional<Employee> employeeOptional = employeeRepository.findByNameJPQL("Jack");
        System.out.println(employeeOptional.isPresent()); // false

        Assertions.assertFalse(employeeOptional.isPresent());
    }

}

參考github


4 則留言:

  1. 你好 我是剛學spring boot沒多久,想請您幫忙看一下我哪裏寫錯,這是我在stack裡的問題
    https://stackoverflow.com/questions/67587438/java-lang-nullpointerexception-null-when-try-to-inject-spring-container-in-cont


    我用留覽器開會顯示500,系統顯示注入的repositoy是空值,我想了好幾個小時都找不到為何,這是spring的bug嗎

    回覆刪除
  2. 你在indexController注入jpaRepository2實例的註解寫錯了,不是用@Resource,應改成@Autowired。

    另外Java類別,介面請用開頭大寫,請參考Java程式命名慣例
    https://matthung0807.blogspot.com/2019/05/java-naming-convention.html

    回覆刪除
  3. 如果你要用@Resource注入,因為注入規則預設是依照屬性名稱來注入符合名稱的對象,所以應該改為@Resource(name = "jpaRepository2")

    回覆刪除