[오류]IdentifierGenerationException

gamja·2022년 12월 1일
0
post-thumbnail

아주 골치아픈 오류 발생...


오류 내용

nested exception is org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save():


발생 상황

게시글 내용을 저장하려고 save()를 사용했는데 위와 같은 오류 메시지가 떴다.

save()

postRepository.save(saveDto.toEntity());

필요한 부분만 뽑아오자면,

UserEntity

@Entity
@Getter
@Table(name = "tb_users")
public class User {
    @Id
    @Column(name = "user_id")
    private String userId;

    @Column(name = "user_password")
    private String userPassword;
    
    public User(String userId){
        this.userId = userId;
    }

}

PostEntity

@Entity
@Getter
@Table(name="tb_post")
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "post_id")
    private int postId;

     @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "seller_id", referencedColumnName = "user_id")
    private User user;
    
     @Builder
    public Post(String postTitle, String postContent,
                int price, String proposalYn, int regionId, int categoryId, String userId,
                LocalDate createdAt, Date updatedAt, String status, String deletedYn,
                int viewCnt, int likeCnt)
        {
        this.postTitle = postTitle;
        this.postContent = postContent;
        this.price = price;
        this.proposalYn = proposalYn;
        this.createdAt = Date.valueOf(createdAt);
        this.updatedAt = updatedAt;
        this.status = status;
        this.deletedYn = deletedYn;
        this.viewCnt = viewCnt;
        this.likeCnt = likeCnt;
        this.setRegion(regionId);
        this.setCategory(categoryId);
        this.setUser(userId);

    }

}

builder 가 저리 길어도 되는 건지 모르겠음... 다른 블로그 보면 엄청 짧던데. 근데 저렇게 안 넣어주면 이상하게 default값이 아닌 null로 들어가서 불편하게 java에서 세팅을 해줘야 함. 지금 생각해보니 @Default 어노테이션을 사용 안 해서 그런 것 같기도 하다.


오류 원인

후보1) save() 함수를 호출하기 전에 id 값이 설정되어 있어야 하는데, User의 id값이 설정되어 있지 않기 때문에 오류가 났다.

-> id가 int가 아닌 String이기 때문에 @GeneratedValue를 사용하지 않고, 값을 User Entity에 넣어줬는데 이와 같은 오류가 났다. 다른 분들의 경우는 @GeneratedValue 를 작성해줌으로써 해결했다고 하는데, id가 String인 나에게는 해당되지 않는 듯하다. 또는 직접 식별자를 할당 해도 된다고 해서 User의 생성자를 통해서 userId를 세팅해줬다. 같은 방법으로 다른 것들은 다 잘 들어갔는데, userId만 값이 할당 되지 않음.

https://hangjastar.tistory.com/241
https://hoontinparis.tistory.com/121

후보2) @ManyToOne으로 Post와 User가 연관되어 있는 상태인데, CUD와 같이 데이터를 변경할 때는 @ManyToOne(cascade = CascadeType.ALL) cascade를 작성해줘야 한다고 한다. 나같은 경우는 ALL, DETACH 등 다 해봤는데 결국 안 됐다.

몇 시간동안 오류에 시달리다가 결국 PostRepository에 save() 메소드를 만들어 sql문을 직접 작성해서 저장해봤다. 하지만... userId를 제외하고 나머지 값은 제대로 저장되었다. 정말 무서웠다😱 지독한 오류에 걸린 느낌..?

 @Query(value = "insert into tb_post(seller_id, post_title, post_content, created_at, updated_at, status, deleted_yn, price, price_proposal_yn, region_id, category_id, view_cnt, like_cnt) " +
            	"values (:#{#post.user.userId},:#{#post.postTitle}, :#{#post.postContent},:#{#post.createdAt},:#{#post.updatedAt}, :#{#post.status}, :#{#post.deletedYn}, :#{#post.price}, :#{#post.proposalYn}, :#{#post.region.regionId}, :#{#post.category.categoryId}, :#{#post.viewCnt}, :#{#post.likeCnt})",nativeQuery = true)
    @Modifying
    @Transactional
    public int postSave(@Param(value = "post") Post post);

나는 이 오류의 근본적인 원인을 @ManyToOne 으로 둘을 연관 시켜놨기 때문에 발생한 것이라고 봤다. 따라서 그냥 그 근본이 되는 원인을 없애 버리기로 했다.


해결 (완전한 해결은 아님)

결국 IdentifierGenerationException 오류의 원인은 알겠지만, Entity를 유지하면서 이를 해결할 방법을 못 찾았다. 따라서 나는 @ManyToOne을 버리기로 했다.

@Entity
@Getter
@Table(name="tb_post")
public class Post {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "post_id")
    private int postId;

    @Column(name = "seller_id")
    private String userId;			// 수정 후
}

이렇게 한 뒤 연관된 코드를 다 수정해 주고, 다시 save()를 해보니 잘 됐다. 이게 맞나 싶다. 다음부터 id는 웬만하면 int나 Long으로 해서 @GeneratedValue를 사용해주는 것이 좋을 것 같다😇


12.04

유튜브 최범균 님의 JPA 강의를 보니 되도록이면 @Embeddable을 사용하는 것이 좋고, 연관 매핑은 신중히 사용해야 된다고 한다.
매핑을 통해 연관된 값을 바로바로 조회할 수 있다는 장점이 있지만, 그 장점만 생각하고 연관 매핑을 하는 것은 좋지 않다고 한다.

profile
눈도 1mm씩 쌓인다.

0개의 댓글