Skip to content

[Bug] User 엔티티 follow 관련 연관관계 메소드 오류 #27

@oownahcohc

Description

@oownahcohc

버그 설명

  • follow 로직 실행 중 새로 생성된 팔로우 정보를 master 유저의 following 필드에 저장, target 유저의 follower 필드에 저장.
  • 해당 비즈니스 로직에서 바로 두 정보를 조회하면 조회 성공.
  • 다른 비즈니스 로직에서 조회 시 팔로우 정보가 master 유저의 follower 필드에 저장되어 있고, target 유저의 following 필드에 저장되어 있어 조회가 제대로 이루어지지 않는 버그가 발생.

followUser 로직 설명

  1. master 유저가 targer 유저를 팔로우하기 위해 followUser 호출
followService.followUser(targetUserId, userId);
  1. targetUserId 와 userId 로 각각 user 찾아옴
        User me = UserServiceUtils.findByUserId(userRepository, userId);
        User targetUser = UserServiceUtils.findByUserId(userRepository, targetUserId);
  1. 이미 팔로우중인 유저인지 검증
        FollowServiceUtils.validateNotFollowingUser(followRepository, targetUser.getId(), me.getId());
  1. Follow 정보를 생성하고 follow 테이블에 저장한다
        Follow followInfo = followRepository.save(Follow.newInstance(targetUser, me));
  1. Follow 엔티티에 followee 로 매핑된 target 유저의 follower 리스트에 add
        targetUser.addFollower(followInfo);
  1. Follow 엔티티에 follower 로 매핑된 master 유저의 following 리스트에 add
       me.addFollowing(followInfo);

unfollowUser 로직 설명

  1. master 유저가 targer 유저를 언팔로우하기 위해 unfollowUser 호출
followService.unfollowUser(targetUserId, userId);
  1. targetUserId 와 userId 로 각각 user 찾아옴
        User me = UserServiceUtils.findByUserId(userRepository, userId);
        User targetUser = UserServiceUtils.findByUserId(userRepository, targetUserId);
  1. master 유저가 target 유저를 팔로우하는 팔로우 정보 가져오기
        Follow followInfo = FollowServiceUtils.findByFolloweeUserIdAndFollowerUserId(followRepository, targetUserId, userId);
  1. 가져온 팔로우 정보를 각각 유저의 팔로우 관리 리스트에서 삭제
        me.deleteFollowing(followInfo);
        friend.deleteFollower(followInfo);
  1. 팔로우 정보 삭제
       followRepository.delete(followInfo);

해당 이슈와 관련된 User 엔티티 정보

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User extends AuditingTimeEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id", nullable = false)
    private Long id;

    /**
     * 나를 팔로우하는 유저 List
     */
    @OneToMany(mappedBy = "follower", cascade = CascadeType.ALL, orphanRemoval = true)
    private final List<Follow> followers = new ArrayList<>(); // 여기 있는 followee 는 다 this(User), follower 는 나를 팔로우하는 애들

    /**
     * 내가 팔로우하는 유저 List
     */
    @OneToMany(mappedBy = "followee", cascade = CascadeType.ALL, orphanRemoval = true)
    private final List<Follow> followings = new ArrayList<>(); // 여기 있는 followee 는 다 내가 팔로우하는 friend, follower 는 this(User)


    /**
     * <b>나를 팔로우하는 유저 추가</b><br>
     * @param follower 나를 팔로우하는 유저
     */
    public void addFollower(Follow follower) {
        this.followers.add(follower);
    }

    /**
     * <b>내가 팔로우하는 유저 추가</b><br>
     * @param myFollowing 내가 팔로우하는 유저
     */
    public void addFollowing(Follow myFollowing) {
        this.followings.add(myFollowing);
    }

    public List<User> getMyFollowers() {
        return this.followers.stream()
                .map(Follow::getFollower)
                .collect(Collectors.toList());
    }

    public List<User> getMyFollowings() {
        return this.followings.stream()
                .map(Follow::getFollowee)
                .collect(Collectors.toList());
    }

    public void deleteFollower(Follow follower) {
        this.followers.remove(follower);
    }

    public void deleteFollowing(Follow following) {
        this.followings.remove(following);
    }
}

해당 이슈와 관련된 Follow 엔티티 정보

@Entity
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class Follow extends AuditingTimeEntity {

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

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "followee_id")
    private User followee;  // 팔로우 당하는 유저

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "follower_id")
    private User follower;  // 팔로우 하는 유저

    private Follow(final User followee, final User follower) {
        this.followee = followee;
        this.follower = follower;
    }

    public static Follow newInstance(User followee, User follower) {
        return new Follow(followee, follower);
    }
}

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions