spring

뉴스피드 트러블슈팅

seungmin576 2025. 2. 16. 20:05

2025-02-16

Board entity를 만들고 실행하던 중 이런 에러가 나타났다.

Hibernate: 
    alter table board 
       drop 
       foreign key FKfyf1fchnby6hndhlfaidier1r
2025-02-16T19:44:54.506+09:00  WARN 27568 --- [newsFeed] [           main] o.h.t.s.i.ExceptionHandlerLoggedImpl     : GenerationTarget encountered exception accepting command : Error executing DDL "
    alter table board 
       drop 
       foreign key FKfyf1fchnby6hndhlfaidier1r" via JDBC [Table 'newsfeed.board' doesn't exist]

org.hibernate.tool.schema.spi.CommandAcceptanceException: Error executing DDL "
    alter table board 
       drop 
       foreign key FKfyf1fchnby6hndhlfaidier1r" via JDBC [Table 'newsfeed.board' doesn't exist]

하고 블라블라 ~~~~~~~~~ 하다가

Caused by: java.sql.SQLSyntaxErrorException: Table 'newsfeed.board' doesn't exist

여기서 핵심은 GenerationTarget encountered exception accepting command : Error executing DDL 이라는 문구인데 

GenerationTarget에서 예외 수락 명령이 발생했습니다: DDL 실행 중 오류 발생

파파고한테 번역기를 돌리니 이렇다고 한다.

주로 jpa를 사용할때 나타나는 오류이며 DDL 명령어 실행 중에 발생한다고 한다

그럼 Board 라고 이름을 지은 entity에 문제가 생긴 것 같으니 찾아본다.

package com.example.newsfeed.board.entity;

import com.example.newsfeed.common.entity.BaseEntity;
import com.example.newsfeed.user.entity.User;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.Setter;

@Entity
public class Board extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String title;

    @Column(nullable = false)
    private String contents;

    @ManyToOne
    @JoinColumn(name = "user_id")
    @Getter
    private User user;

    @Setter
    @Getter
    private Long like;
}

문법적으로는 오류가 없다.

하지만 '좋아요'라는 의미에서 지은 like 라는 필드가 생각해보니 jpa가 쿼리문을 작성해 줄때 SQL 예약어와 같아서 오류가 나는 것 같으니 이를 바꿔야할듯하다.

 

like 필드를 likes로 바꾸니 해결됐다. 다음부터는 entity 클래스의 필드명을 지을 때 SQL 예약어와 같은지 생각하고 지어야겠다.

 

 

 

2025-02-19

회원 탈퇴 기능을 만들고 나니 그 회원이 아무 게시물이나 댓글, 좋아요 등 행동이 없으면 탈퇴가 잘 되지만 뭐라도 하나 하면 회원탈퇴가 안된다.

2025-02-19T13:05:41.877+09:00 ERROR 17856 --- [newsFeed] [nio-8080-exec-4] o.h.engine.jdbc.spi.SqlExceptionHelper : Cannot delete or update a parent row: a foreign key constraint fails (`newsfeed`.`friend`, CONSTRAINT `FK3uu8s7yyof1qmenthngm24hry` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`))
2025-02-19T13:05:41.920+09:00 ERROR 17856 --- [newsFeed] [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.dao.DataIntegrityViolationException: could not execute statement [Cannot delete or update a parent row: a foreign key constraint fails (`newsfeed`.`friend`, CONSTRAINT `FK3uu8s7yyof1qmenthngm24hry` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`))] [/* delete for com.example.newsfeed.user.entity.User */delete from user where id=?]; SQL [/* delete for com.example.newsfeed.user.entity.User */delete from user where id=?]; constraint [null]] with root cause

Cannot delete or update a parent row: a foreign key constraint fails (`newsfeed`.`friend`, CONSTRAINT `FK3uu8s7yyof1qmenthngm24hry` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`))

부모 행을 삭제하거나 업데이트할 수 없습니다: 외래키 제약 조건이 실패합니다 ('newsfeed' gilsfriend', 제약 조건 'FK3uu8s7yof1qmenthm24hry' 외래 키 ('user_id') 참조 '사용자' ('id')

 

자식 테이블 입장에선 부모 테이블의 열과 일치하는 데이터를 가져와야 하는데 이 무결성이 깨지기 때문에 삭제를 못하는 것 같다.

 

그럼 JPA로 부모테이블에서 자식테이블로 oneToMany를 사용하여 양방향 매핑이 되게 한뒤 oneToMany에 cascade.remove나 all을 적어주면 될 것 같다.

package com.example.newsfeed.user.entity;

import com.example.newsfeed.comment.entity.Comment;
import com.example.newsfeed.common.entity.BaseEntity;
import com.example.newsfeed.friend.entity.Friend;
import com.example.newsfeed.friend.entity.FriendsRequest;
import com.example.newsfeed.like.entity.Likes;
import com.example.newsfeed.post.entity.Post;
import jakarta.persistence.*;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

@Getter
@Setter
@Entity
@NoArgsConstructor
public class User extends BaseEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false)
    private String name;

    @Column(nullable = false, unique = true)
    private String email;

    @Column(nullable = false)
    private String password;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Post> posts;

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Likes> likes;

    @OneToMany(mappedBy = "requester", cascade = CascadeType.ALL)
    private List<FriendsRequest> sentFriendsRequests;
    @OneToMany(mappedBy = "receiver", cascade = CascadeType.ALL)
    private List<FriendsRequest> receiveFriendsRequests;

    @OneToMany(mappedBy = "receiver", cascade = CascadeType.REMOVE)
    private List<Friend> receiveFriends;
    @OneToMany(mappedBy = "requester", cascade = CascadeType.REMOVE)
    private List<Friend> requesterFriends;


    public User(String email, String password, String name) {
        this.email = email;
        this.password = password;
        this.name = name;
    }

    private User(Long id) {
        this.id = id;
    }

    public static User fromUserId(Long id) {
        return new User(id);
    }
}

 

이렇게 했더니 회원 탈퇴 시 회원의 행적이 다 삭제되며 탈퇴가 제대로 되는 모습이다.

만약 회원 탈퇴를 해도 행적은 남게 하려면 어떻게 해야할지 생각해봐야겠다.

 

'spring' 카테고리의 다른 글

관계형DB일때 N:M 연관관계 @ManyToMany  (0) 2025.02.24
@Mock  (0) 2025.02.24
HttpServletResponse 메서드  (0) 2025.02.12
Bcrypt  (0) 2025.02.10
scheduleJPA 트러블슈팅  (1) 2025.02.07