2 minute read


이제껏 미뤘던 사이드 프로젝트를 좀 만져봤다. asfasfasfasf
업무상 진행했던 기존 테이블에 맞춰 엔티티를 작성하는 것이 아닌 처음부터 엔티티를 작성해보았다.



@ToString(exclude = "postsList")
@Getter
@NoArgsConstructor
@Entity
public class Users {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private String nickName;

    @Column
    private String password;

    @Column
    private String email;

    @OneToMany(mappedBy = "users", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Posts> postsList = new ArrayList<>();

    @Builder
    public Users(Long id, String nickName, String password, String email) {
        this.id = id;
        this.nickName = nickName;
        this.password = password;
        this.email = email;
    }


    public boolean checkDuplicatedEmail(String email) {
        return this.email.equals(email);
    }
    public boolean checkDuplicatedNickName(String nickName) {
        return this.nickName.equals(nickName);
    }

    public void addPost(Posts post){
        this.postsList.add(post);
    }
}



@ToString
@Getter
@NoArgsConstructor
@Entity
public class Posts {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(length =500, nullable = false)
    private String title;

    @Column(columnDefinition = "TEXT" , nullable = false)
    private String content;

    @ManyToOne
    private Users users;

    @Embedded
    private ContactInfo contactInfo;


    @Builder
    public Posts(Long id, String title, String content, ContactInfo contactInfo) {
        this.id = id;
        this.title = title;
        this.content = content;
        this.contactInfo = contactInfo;
    }

    public void putUser(Users users){
        this.users = users;
    }
}



두 가지 엔티티의 관계, Users 가 Posts를 작성할 수 있도록 하였다.
어제 본 애그리거트 기준으로 봤을 때, Posts가 Users에 의해 생성되는게 맞다는 판단을 하였다.
Users @OneToMany 관계인 postsList의 CaseCade 타입을 지정해 주어야 Posts 수정이 가능했다.


그래서 나오게 된 save 코드


@RequiredArgsConstructor
@Service
public class PostsService {
    private  final UsersRepository usersRepository;

    @Transactional
    public void save(Long id,PostsSaveRequestDto requestDto){
        Users users = usersRepository.findById(id)
                .orElseThrow(()-> new IllegalArgumentException("해당 유저가 존재하지 않습니다. id ="+id));


        Posts posts = requestDto.toEntity();
        users.addPost(posts);
        posts.putUser(users);
        usersRepository.save(users);
    }
}


내가 기존에 알던 것과 다르게 save를 다시 진행하지 않으면 Posts가 저장되지 않았다.
자체 필드만 영속성 부여로 save가 되는 것인지 아님 내가 트랜잭션 단위를 잘 못 알고 있는 건지 좀 찾아봐야겟다.



다음은 간단한 회원가입과 중복체크 서비스 부분


@RequiredArgsConstructor
@Service
public class UsersService {
    private final UsersRepository usersRepository;

    @Transactional(rollbackFor = Exception.class)
    public Long save(UsersSaveRequestDto requestDto){
        if(!checkDuplicatedEmail(requestDto.getEmail()))
            throw new IllegalArgumentException(String.format("email=[%s]가 중복됩니다.",requestDto.getEmail()));

        if(!checkDuplicatedNickName(requestDto.getNickName()))
            throw new IllegalArgumentException(String.format("nickName=[%s]가 중복됩니다.",requestDto.getNickName()));

        return usersRepository.save(requestDto.toEntity()).getId();
    }

    public boolean checkDuplicatedEmail(String email){
        return usersRepository.findAll().stream()
                .noneMatch(x -> x.checkDuplicatedEmail(email));
    }


    public boolean checkDuplicatedNickName(String nickName){
        return usersRepository.findAll().stream()
                .noneMatch(x -> x.checkDuplicatedNickName(nickName));
    }
}



그리고 테스트 코드


@RunWith(SpringRunner.class)
@SpringBootTest
public class UsersServiceTest {

    @Autowired
    UsersRepository usersRepository;

    @Autowired
    UsersService usersService;

    @Before
    public void setUp() throws Exception {
        Users user1 = Users.builder()
                .email("email@email.com")
                .nickName("nickname")
                .password("123123")
                .build();
        usersRepository.save(user1);

        Users user2 = Users.builder()
                .email("email1@email.com")
                .nickName("nickname1")
                .password("123123")
                .build();
        usersRepository.save(user2);
    }

    @After
    public void tearDown() throws Exception {
        usersRepository.deleteAll();
    }

    @Test
    @Transactional
    public void save() throws Exception{
        UsersSaveRequestDto dto = UsersSaveRequestDto.builder()
                .email("email@email.coma")
                .nickName("123")
                .build();

        Long id = usersService.save(dto);

        Users user = usersRepository.findById(id).orElseThrow(
                () -> new IllegalArgumentException("해당 유저가 없습니다. id =" + id));
        System.out.println("element" + user);

        /*
        usersRepository.findAll().stream()
               .forEach(x-> System.out.println("element" + x));
         */
    }

    @Test
    public void checkDuplicatedEmail() {
        System.out.println("checkduplemail : " + usersService.checkDuplicatedEmail("email@email.com"));
    }

    @Test
    public void checkDuplicatedNickName() {
        System.out.println("checkduplemail : " + usersService.checkDuplicatedNickName("nickName"));
    }
}


확실히 myBatis 때보다 속도가 좋긴하다.


간단하게 오늘은 끗