게시글
질문&답변
2024.01.21
스프링 통합 테스트 시 @Transactional로 DB를 롤백 시키는데 id는 여전히 건너뛰어지는 이유
안녕하세요! id 자동 생성 전략을 사용 할 시, 엔티티의 ID는 DB의 값을 바탕으로 주입되게 됩니다. [롤백 설정이 된 테스트에서 인서트 쿼리가 나가는 이유] "id 값을 부여하는 건 결국 DB라고 생각했는데" 에서 이미 답을 말씀하셨는데요! 롤백 설정을 통해 엔티티를 DB에 커밋하지는 않았지만, DB 에서 해당 엔티티의 아이디를 자동으로 생성해주는(부여해주는) 과정에서 호출된 DB의 설정 및 함수(AUTO_INCREMENT, nextval 등) 는 롤백되지 않아서 id의 값은 올라갑니다.
- 0
- 2
- 543
질문&답변
2024.01.17
다형적 참조의 오버라이딩
안녕하세요! 해당 부분에서 저도 비슷한 의문이 있어서 알아본 결과를 공유드립니다! 먼저,매서드를 사용하는 변수의 참조값을 따라 인스턴스를 찾고 (Child) 인스턴스 내의 변수 타입과 동일한 클래스 타입부터 시작하여(Parent?) 메서드를 찾는다이 부분에서 "변수 타입과 동일한 클래스 타입" 을 Parent 라고 생각 할 수 있지만, 사실 그렇지 않습니다. 한 번 간단한 테스트를 돌려봤는데요! @Test void foo_instance_info_wildcard(){ Parent foo = new Child(); Class aClass = foo.getClass(); // 인스턴스의 클래스 정보 String simpleName = aClass.getSimpleName(); // 해당 클래스의 이름(패키지 미포함) System.out.println(simpleName); assertEquals("Child", simpleName); } 해당 테스트는 통과하며, 출력 결과는 Child 로 나옵니다. 이 부분에서 실제 런타임에서 동작하는 타입과 (우리가 getSimpleName() 으로 가져온 타입) 컴파일 시점의 타입이(명시된 Parent타입) 다르다는 것을 확인 가능합니다. 그리고 이 부분에 대한 글이 있어, 공유드립니당[Compile-Time Type VS Run-Time Type] 결과적으로 "변수의 타입과 같은 Parent에서 탐색하는 것" 이 아닌, 인스턴스가 가진 타입 정보인 Child부터 시작하여 Parent 측으로 올라가는 식으로 매서드를 찾게 됩니다.
- 0
- 2
- 438
질문&답변
2024.01.15
public String / Long과 public void의 차이는 무엇인가요?
안녕하세요! 자바 매서드는 접근제어자 리턴타입 매서드이름 순서로 선언됩니다 public(접근제어자) Long(리턴타입, 이 매서드는 Long 타입을 리턴해야 한다는 뜻) 매서드이름 이라고 생각하시면 될 것 같습니다! [더 자세한 내용에 대한 블로그] 이 부분에 대해서 위 블로그 한번 참고 해 보셔도 좋을 것 같습니다! 감사합니다.
- 0
- 1
- 405
질문&답변
2024.01.15
연관관계 메서드 관련 질문
안녕하세요! public void addchildCategory(Category child){ // 인자로 들어오는 child 를 set this.child.add(child); child.setParent(this); } public void addchildCategory(Category child){ this.child.add(child); this.parent = child; // 이 클래스의 인스턴스를 set } 위 코드는 인자로 들어오는 Category 를 set 하느냐, 아니면 해당 매서드의 주체가 되는 클래스의 객체를(인스턴스를) set 하느냐고 하는 차이가 있습니다. 즉 위계를 어느 쪽으로 하냐의 차이가 있습니다. 인자로 들어오는 부분이 경우 부모는 해당 addChildCategory 를 호출하는 쪽이 됩니다. 이쪽에서 set 하는 경우이 경우 부모는 들어오는 인자쪽이 됩니다. (이에 따라 매서드 이름도 addParent 정도가 좋을 것 같습니다) 정리하자면 해당 변경은 기능상으로는 비슷하지만, parent 필드를 바꾸는 쪽이 달라지는 차이가 있습니다. (이 매서드를 호출하는 쪽 vs 인자로 사용되는 쪽) 감사합니다.
- 0
- 1
- 244
질문&답변
2024.01.13
게시판에서 삭제된 댓글을 보여주기 위해 Spring Data JPA에서는 어떻게 접근해야 할까요?
안녕하세요! 현재 delete 필드의 처리 때문에 다른 로직들 (조회 로직이라던지) 도 영향을 받는 점이 마음에 들지 않아서 질문 해 주신 듯 합니다! 그래서 한번 delete 필드가 쓰이는 상황 두 가지를 보고, 어떻게 사용해야 할 지 한 번 고민해봤어요. delete 가 false 여야 하는 생성 상황 (사진)상황을 비슷하게 만들기 위해 임의로 엔티티를 하나 선언했습니다. 아마도 이 엔티티는 생성 할 때는 isDeleted 라는 필드가 false 여야 하고, 삭제 할 땐 (실제론 수정이 되겠죠) true 로 변경되어야 할 것 같아요! 그렇다면 한번 이 엔티티를 save 해보고 해당 isDeleted 필드가 어떻게 DB에 들어가는지 확인 해 봤습니다. (사진)위와 같이 우리가 명시 선언하지 않은 IS_DELETE 는 FALSE 로 들어갑니다. 이 이유는 자바 기본 타입 boolean 의 기본 값이 false 로 설정되어있기 때문입니다. (그러나 생성자 매서드에서 이 boolean 이 false 임을 명시 선언하셔도 괜찮지 않을까 생각이 됩니다.) (사진) 이것으로 생성 시 해당 필드의 기본값이 false 가 되도록 만드는 작업을 여타 DB 관련된 프로세스들과(@Where 어노테이션이라던지) 떼어내고, 자바 코드로 관리 가능하게 했습니다. 업데이트 시 (즉 true 가 되어야 할 시)해당 작업 이후는 JPA 의 변경 감지(더티체킹) 을 사용하시거나, 아니면 JPQL등 편하신 방법을 사용하시어 해당 필드를 TRUE 로 업데이트 하시면 될 것 같습니다! 감사합니다.
- 1
- 2
- 506
질문&답변
2024.01.12
enum
안녕하세요! 엔티티의 필드로 자바의 Enum 을 사용해야 하는 분명한 이유가 있다면 (예를 들어 해당 필드가 RED, BLUE ...와 같이 몇 가지 경우의 수로 정해져있고, 앞으로 추가되는 필드들도 이 친구들과 매우 비슷할 것이라고 예상된다면) 사용해도 전혀 상관 없다고 생각합니다. 더불어 걱정하시는 부분은 아마도 "그렇다면 해당 자바 Enum 타입의 필드가 어떻게 DB에 들어갈까?" 에 대해서 걱정하고 계신 것 같습니다! @Enumerated private FooEnum fooEnum; // 해당 방식의 경우 이넘 필드의 "순서" 대로 삽입됩니다. @Enumerated(EnumType.STRING) private FooEnum fooEnum; // 해당 방식의 경우 이넘 필드의 "이름" 으로 삽입됩니다.기본적으로는 위 주석으로 설명드린 바와 같이 DB에 저장이 되는데요! 저장되는 형식을 @Convert 어노테이션을 사용해서 변환시키는 방법도 존재합니다. [@Convert 및 @Converter 사용 예시] 결론적으로 질문 주신 "엔티티에서 언제 enum타입을 사용할지 String타입을 사용할지 기준" 에 대해서 답변해드리자면 Enum 클래스를 사용하면 해당 필드에 존재 할 수 있는 값들이 제한됩니다 (Enum에 선언된 값들만 존재 할 수 있겠죠) 즉, Enum 클래스는 우리가 미리 선언한 몇 개의 값들(위 예시로 들었던 RED, BLUE...) 과 해당 값과 매우 비슷한 성질의 (YELLOW...) 값들만을 사용 할 것임이 확실 할 때 사용합니다. (즉, 해당 비슷한 성질의 값들을 모아놓는 역할이며 다른 값들을 허용하지 않음이 보장됩니다 - JAVA 관점에서요) 반면 String 은 어떤 값이든 해당 필드에 들어 갈 수 있다는 것을 의미합니다. 해당 필드에 별다른 제한을 걸지 않겠다는 뜻이죠. 필요하신 상황에 따라 달리 사용하시면 될 듯 합니다! 감사합니다.
- 0
- 1
- 347
질문&답변
2024.01.12
자동완성 기능설정이 궁금합니다.
안녕하세요! 인텔리제이 keymap 설정을 확인 해 보시면 될 것 같습니다! (사진)위처럼 Code Completion - Basic 이 Ctrl + space 로 잘 되어있는지 확인해주세요. [해당 이슈에 대한 블로그 링크] 자세한 방법은 위 링크로 남겨두었습니다. 감사합니다
- 0
- 2
- 221
질문&답변
2024.01.11
특정 타입으로 조회 시 빈 이름을 지정하는 테스트 코드 관련 질문
안녕하세요! 두 번째 테스트의 @DisplayName("부모 타입으로 조회 시 자식이 둘 이상 있으면, 빈 이름을 지정하면 된다.") 에 힌트가 존재합니다. 부모 타입을 상속하는 자식이 하나라면 스프링은 하나의 자식을 잘 맵핑하지만, 상속하는 자식이 두 개 이상이라면 실제 구현체 타입이 어떤 것인지 지정 해 줘야 합니다. DiscountPolicy rateDiscountPolicy = ac.getBean("rateDiscountPolicy", DiscountPolicy.class); 위 라인에서 볼 수 있듯이, DiscountPolicy 라는 상위 추상의 타입으로 해당 rateDiscountPolicy 를 사용하려고 하는 상황이고, assertThat(rateDiscountPolicy).isInstanceOf(RateDiscountPolicy.class)자바의 instanceOf 키워드를 통해 해당 DiscountPolicy 타입의 객체가 실제 어떤 인스턴스인지 검증하려는 테스트입니다. 정리하자면 구체화 타입인 RateDiscountPolicy.class로 인스턴스를 확인한 이유 는 해당 타입(DiscountPolicy 라는 인터페이스 타입)은 두 개 이상의 자식을 가지고 있으며, 실제 사용할 인스턴스가 어떤 구현체(자식)에 의해 생성되어야 하는지 설정해줘야 하기 때문입니다. 감사합니다.
- 0
- 2
- 285
질문&답변
2024.01.11
Controller 비즈니스 로직
안녕하세요! service 쪽에서 비즈니스 로직에 대한 상세한 내용을 직접 처리하고, Controller 는 이 서비스를 가져다 쓴다고 보면 좋을 것 같습니다. (즉 비즈니스 로직의 수행자는 서비스에 존재하는 매서드입니다. 컨트롤러는 이 매서드를 부르고 있습니다) 감사합니다.
- 0
- 1
- 303
질문&답변
2024.01.11
If else
(사진)이렇게 if 문 뒤에 중괄호를 여닫아 주시거나 ({})(사진)아예 중괄호를 사용하지 않으시면 해결 됩니다! 현재 오류가 나는 이유는 else 전에 있는 중괄호 '}' 가 매서드의 끝지점으로 판별되어서 인 것 같아요!(사진)감사합니다.
- 0
- 3
- 176