@ModelAttribute 객체가 바인딩 되지 않는 오류

이번 프로젝트를 진행하면서, 요청으로 받은 파라미터들이 @ModelAttribute 객체에 바인딩이 되지 않는 이슈를 겪어 이에 대해 정리해보고자 한다.

지금 진행하는 프로젝트에서 JPA와 MyBatis를 함께 사용하는 것이 아닌 오로지 MyBatis만 사용하면서 기존의 방식과 다른점으로 머리속이 복잡해지면서 많은 오류를 겪었다.

 

JPA에서는 Entity 객체에 @Entity 어노테이션을 붙여 테이블이 생성하도록 해준다.

@Entity 객체에 기본 생성자가 없을 경우에는 JPA가 작동하지 않을 것이다.

그 이유는 JPA는 Reflection API라는 것을 사용하여 객체를 생성해 기본 생성자가 필요하기 때문이다.

 

그래서 보통 Entity 객체에는 기본 생성자와 값 생성자가 포함된다. 그리고 Setter 사용은 지양된다.

 

[JPA] Entitiy에서 왜 Setter를 사용하지 말라고 할까?

어느 책에서나 어느 강의에서나 Entity에서는 Setter를 사용하는 것을 지양한다고 한다. 그렇다면 왜 setter를 지양할까 ? setter를 지양하는 이유 사용한 의도를 쉽게 파악하기 어렵다. Member member = new

hstory0208.tistory.com

근데 위 방법을 그대로 MyBatis를 사용하는 프로젝트에서 DTO들을 만들지 않고

기본 생성자와 값 생성자 총 2개의 생성자가 있는 VO만 사용하여 데이터를 주고 받으려 하다가 여기서 문제가 발생했다.


@ModelAttribute 객체에 바인딩이 되지 않은 이유

내가 만든 VO를 보면 다음과 같다.

@Getter
@NoArgsConstructor
public class User {
    private String user_email;
    private String user_name;
    private String user_pwd;
    private Integer user_status;

    @Builder
    public User(String user_email, String user_name, String user_pwd, Integer user_status) {
        this.user_email = user_email;
        this.user_name = user_name;
        this.user_pwd = user_pwd;
        this.user_status = user_status;
    }
}

위 코드는 @NoArgConstructor 를 선언했고 모든 필드를 포함하는 생성자가 있으므로

@NoArgConstructor + @AllArgsConstructor 를 같이 사용했다고 볼 수 있다.

 

이런식으로 객체가 구성되어있을 때 발생할수 있는 문제점은 다음과 같았다.

NoArgsConstructor과 AllArgsConstructor 둘 다 있는 경우 NoArgsConstructor 호출하고, setter 호출하여 param을 필드에 각각 초기화한다.

 

그런데 VO이기 때문에 setter가 없다.

그래서 Form 데이터에서 받아온 param을 필드에 각각 초기화 해주지 못해 데이터가 NULL인 문제가 발생했다.

 

이 처럼 롬복의 생성자 어노테이션을 VO에 사용해 생성자가 2개일 경우 @ModelAttribute 로 Form데이터를 받아올 때 데이터 바인딩 이슈가 발생할 수 있다.


요약

생성자가 1개일 경우

@ModelAttribute는 생성자가 1개면 그 생성자를 통해 객체를 생성.

 

생성자가 2개 이상일 경우

매개변수 없는 생성자를 통해 객체를 생성하고 Setter로 값을 세팅

 

 

JPA를 사용하면서 습관처럼 VO에 @NoArgConstructor를 붙이고 이 VO만 사용하면서 이번 이슈를 겪게 되었는데

이러한 어노테이션들을 사용하기 전에 확실히 해당 어노테이션이 어떤식으로 동작하는지 알고 사용해야한다는 것을 크게 깨달았다..