REST API 옮기기1-2: 뒤늦게 테스트코드 작성하기 (+ @ColumnDefault & @DynamicInsert & @ PreXXX)

dev_314·2022년 8월 26일
0

JPA - Trial and Error

목록 보기
7/16

Repository - Service -Controller가 잘 작동하는지 확인하는것에 급급하다보니 Test code 작성을 까먹었다. 지금이라도 작성해보잣

Repository Test

package wonju.howcook.repository;

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.transaction.annotation.Transactional;
import wonju.howcook.domain.User;

import javax.persistence.EntityManager;

import static org.assertj.core.api.Assertions.*;

@Transactional
@SpringBootTest
class UserRepositoryTest {

    @Autowired
    EntityManager em;

    @Autowired
    UserRepository userRepository;

    @Test
    void 회원가입() {
        User user = new User("email1", "password1", "nickname1");
        userRepository.save(user);

        em.flush();
        em.clear();

        User findUser = userRepository.findById(user.getId());

        assertThat(user.getId()).isEqualTo(findUser.getId());
        assertThat(user.getPassword()).isEqualTo(findUser.getPassword());
    }

    @Test
    void findById() {
    }

    @Test
    void findByNickname() {
    }
}

Trials and Errors

문제1. not-null property references a null or transient value

  • nullable = false로 설정한 필드들에 값을 넣어주지 않아서 문제가 발생했다.

해결1. 변수에 직접 초기값을 설정해준다.

	...
    
    @Column(name = "THUMBNAIL_URL", length = 2048, nullable = false)
    @ColumnDefault(value = THUMBNAIL_URL_DEFAULT)
    private String thumbnailUrl = THUMBNAIL_URL_DEFAULT;

    @Column(name = "DESCRIPTION", length = 900, nullable = false)
    @ColumnDefault(value = "'hi'")
    private String description = "hi";

	...


정상적으로 테스트가 진행되었다.
그런데 모든 객체가 동일한 값으로 초기화되므로, 서로 다른 초기값으로 설정해야하는 경우에는 사용할 수 없다.

@ColumnDefault란

@ColumnDefault을 사용하면 자동으로 특정 컬럼에 초기값이 삽입될 줄 알았다. 그런데 그렇지 않더라

분명 DDL로 Default값이 설정되긴 했다.
그래서 직접 Insert쿼리를 날려봤다.

INSERT INTO USERS(EMAIL, NICKNAME, PASSWORD) VALUES("email2", "nickname2", "password2");


직접 쿼리를 날리면 Default값이 들어간다.
@ColumnDefault는 단순히 DB에 제약조건을 추가하는 역할같다. 그러니까, 특정 필드가 null이면 자동으로 값을 초기화 해주는 기능은 수행하지 않는다.

@DynamicInsert, @DynamicUpdate

@DynamicInsert, @DynamicUpdate라는 키워드를 발견했는데, EntityManager로 Persist할 때, null인 필드는 제외하여 Insert, Update 쿼리를 날리는 기능이라고 한다. 내 경우에는 적합하지 않다.

@Entity
@Table()
@DynamicInsert
public class User {
	...
}

PreXXX

내가 원하는건, persist할 때, 특정 필드값이 null이면 초기화를 해주는 것이다. 바로 이에 해당하는 Annotation이 있다.

package wonju.howcook.domain;

import lombok.Getter;
import org.hibernate.annotations.ColumnDefault;
import org.hibernate.annotations.DynamicInsert;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.List;

@Entity
@Table(name = "USERS")
@Getter
@DynamicInsert
public class User {

	...
    
    @PrePersist
    public void free_with_naming_method() {
        if (description == null) {
            description = DEFAULT_DESCRIPTION;
        }

        if (thumbnailUrl == null) {
            thumbnailUrl = DEFAULT_THUMBNAIL_URL;
        }
    }
    
    ...

}

그 외에도@PreDestory, @PreRemove, @PreUpdate Annotation이 있다. 자세한 내부 작동 방식은 추후에 정리해보자
어쨋든 정상 작동한다

profile
블로그 이전했습니다 https://dev314.tistory.com/

0개의 댓글