Spring

[Spring + JPA] No Property Found for Type Exception 에러 해결

lyndaa 2023. 6. 3. 00:00

구현

프로젝트 연극 리스트를 출력하는 과정에 페이징 처리를 구현해보려 한다.

 

1. Service

public Page<Play> selectAll(Pageable pageable){
		return playRepository.findAll(pageable);
	}

Page<T>을 타입으로 지정하면, 반드시 파라미터로 Pageable을 받아야 한다.

 

2. Controller

package com.cc.model.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import com.cc.model.entity.Play;
import com.cc.model.service.PlayService;

@Controller
public class PlayController {
	@Autowired
    private PlayService playService;
	
	@RequestMapping("/play") 
	public String playList(Model model, @PageableDefault(page=0, size=10,sort = "play_id", direction = Sort.Direction.DESC)
    Pageable pageable) {
        Page<Play> list = playService.selectAll(pageable);
        //System.out.println(list.getContent().get(0));
        model.addAttribute("list",list);
        
        return "playlist";
       
    }	
}

@PageableDefault을 사용해 간단하게 구현했다.

이 어노테이션을 사용하여 Repository에 정렬 쿼리를 작성해야하고 페이징 처리, 페이지의 사이즈까지 각각 구현해야 하는 번거로움을 덜 수 있다.

@PageableDefault

- size : 한 페이지에 담을 모델의 수를 정할 수 있다. 기본 값은 10이다.

- sort : 정렬의 기준이 되는 속성을 정한다.
- direction : 오름차순과 내림차순 중 기준을 선택할 수 있다.
- Pageable pageable : PageableDefault 값을 갖고 있는 변수를 선언한다.


문제 상황

org.springframework.data.mapping.PropertyReferenceException: No property 'play' found for type 'Play'

play라는 속성은 도대체 어디서 나온건가 한참을 헤맸는데 바로 Play Entity 속성 중 하나인 play_id 때문에 발생한 오류였다.

스프링 데이터 JPA에서는 변수명을 자동으로 해석하여 매핑하는데  변수명에서 _id와 같은 접미사는 관례적으로 외래키(ForeignKey)를 의미하는 컬럼으로 간주된다. 따라서 play_id 변수를 play로 인식하는 것이 문제였다.

또한, 스프링 데이터 JPA는 _ (underscore)를 예약어로 사용하여 엔티티의 레퍼런스 필드의 프로퍼티를 조회하는 기능도 제공하므로 _ 사용을 피하는 것이 좋다.


문제 해결

@Controller
public class PlayController {
	@Autowired
    private PlayService playService;
	
	@RequestMapping("/play") 
	public String playList(Model model, @PageableDefault(page=0, size=10,sort = "playId", direction = Sort.Direction.DESC)
    Pageable pageable) {
        Page<Play> list = playService.selectAll(pageable);
        model.addAttribute("list",list);
        return "playlist";  
    }	
}

Entity 속성을 playId로 변경하여 문제를 해결하였다~