티스토리 뷰

공부를 안한 게 아니고요...

날마다 일어나는 새로운 오류에 정신을 못차리고 있습니다.

이제 회원관리 구현하는데 이게 무슨...ㅠㅠ

아무튼 며칠 시달리다가 겨우 해결한 오류를 기록해보겠습니다.

 

일단 회원가입 기능을 구현하는데 react에서 axios를 사용해 POST 메서드로 요청을 보내면 계속 PropertyValueException 오류가 났습니다. 

 


 

에러 메세지

org.hibernate.PropertyValueException: not-null property references a null or transient value : com.example.demo.entity.UserEntity.email

 

 

디버깅을 해보면 값이 안들어오고 죄다 null인 모습을 볼 수 있습니다..

그 와중에 password는 값이 왜 들어왔는지 아직도 잘 모르겠어요🙄

 

 

해당 오류에 대해 알아봤습니다.

 

"org.hibernate.PropertyValueException: not-null property references a null or transient value" 오류는 Hibernate에서 발생하는 것으로, 주로 엔티티의 필수 속성이나 외래 키가 null이거나 transient 상태인 경우에 발생합니다. 이를 해결하기 위해서는 다음과 같은 점을 확인해야 합니다.

  1. 엔티티 클래스의 속성이 nullable=false로 설정되어 있는지 확인합니다. 만약 필수 속성이지만 null 값을 허용해야 하는 경우에는 nullable=true로 설정해야 합니다.
  2. 요청 데이터에서 필수로 전달되어야 하는 값을 제대로 전달하고 있는지 확인합니다. 회원가입 요청에서 필요한 모든 필드가 제대로 전달되었는지 확인합니다.

 

⭕해결 1

일단 1번부터 확인하기 위해 UserEntity를 확인해봅니다.

 

주소는 필수적이지 않다고 생각하여 null을 허용하고

나머지는 필수적인 사항으로 지정해놓은 상태였습니다.

혹시나 싶어서 false로 지정해놓은 컬럼들을 다 true로 수정해주고 테스트 해보았지만 결과는 같았습니다.

 

 

 

 해결 2

2번 사항은...당연히 모든 필드를 다 기입하고 테스트했기 때문에 생각해 볼 필요도 없었습니다.

 

 

 

⭕해결 3 - axiox 수정

 

[변경 전 코드]

let register = () => {
    axios.post('http://localhost:8082/api/v1/auth/n/register', {
                     userId: user.userId,
                     password: user.password,
                     name: user.name,
                     birth: user.birth,
                     email: user.email
                     addr1: user.addr1,
                     addr2: user.addr2
             },
              {
                 headers: {
                     'Content-Type': 'application/json'
                 }
             })
             .then((res) => {
                // 회원가입 성공
                alert("회원가입이 완료되었습니다!");
                console.log("Response:", res.data);
            })
            .catch((error) => {
                // 회원가입 실패
                alert("회원가입에 실패했습니다. 다시 확인해주세요.");
                console.log("Error:", error);
            });
    }

 

변경 전 코드는 Axios의 post 메서드를 사용하여 POST 요청을 보냈었습니다.

요청 본문에 사용자 정보를 JSON 형식으로 포함시키고, 요청 헤더에 Content-Type을 application/json으로 설정한 것을 볼 수 있습니다.

 

[변경 후 코드]

    let register = () => {
        // 입력란이 비어있을 경우의 경고창
        // if(!user.userId || !user.password || !user.name || !user.password2 || !user.birth || !user.email){
        //     alert("모든 항목을 다 작성해주세요.");
        //     return;  // 함수 실행을 중단하고 반환
        // }
        axios({
            url:'http://localhost:8082/api/v1/auth/n/register',
            method: 'POST',
            data: user
        })
        .then((res) => {
            // 회원가입 성공
            alert("회원가입이 완료되었습니다!");
            console.log("Response:", res.data);
        })
        .catch((error) => {
            // 회원가입 실패
            alert("회원가입에 실패했습니다. 다시 확인해주세요.");
            console.log("Error:", error);
        });
    }

 

변경 후 코드는 Axios의 axios 함수를 사용하여 POST 요청을 보내도록 바꿔주었습니다. 여기서는 요청을 구성하는 객체를 전달하고, 이 객체에는 요청의 URL, 메서드, 그리고 데이터가 포함됩니다. 이 방법은 더 많은 옵션을 설정할 수 있고, 좀 더 유연하게 요청을 조작할 수 있습니다.

 


 

⭕해결 4 - UserDTO 생성과 @JsonProperty("")

 

이게 바로 핵심적인 원인과 해결방법이었습니다.

UserDTO를 생성하고 분명히 롬복을 이용해 애노테이션을 설정했는데

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder

 

롬복이 잘못된건지...

게터와 세터 그리고 생성자들을 제대로 만들어주지 못하고 있었습니다.

이에 대한 해결 방법은 두 가지가 있습니다.

 

✔ 애노테이션을 사용하지않고 게터 세터 생성자들을 다 작성해주기. ( 기존에 쓰던 방법 )

 

  @JsonProperty 애노테이션을 쓰는 방법.

@JsonProperty 이란?
Jackson 라이브러리에서 사용되는 애노테이션입니다. 이 애노테이션은 Java 객체의 필드 또는 메서드에 사용되어 JSON 속성의 이름을 지정할 때 사용됩니다.
예를 들어, Java 객체의 필드명과 JSON의 키(key)명이 다를 때 이를 매핑해야 하는 경우에 @JsonProperty를 사용합니다.

 

package com.example.demo.dto;

import com.fasterxml.jackson.annotation.JsonProperty;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class UserDTO {
	
	private Long id;
	
	@JsonProperty("userId")
	private String userId;
	
	@JsonProperty("password")
	private String password;
	
	@JsonProperty("name")
	private String name;
	
	@JsonProperty("birth")
	private String birth;
	
	@JsonProperty("email")
	private String email;
	
	@JsonProperty("addr1")
	private String addr1;
	
	@JsonProperty("addr2")
	private String addr2;

}

 

이렇게까지 해주니 

드디어 값이 잘 들어오는 것을 확인할 수 있었습니다! 👍

 


 

 

다음엔 DTO를 ENTITY로 변형하는 매핑을 위해 mapstruct에 대해 공부하고 작성해야겠습니다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함