묻고 답해요
144만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
해결됨스프링 DB 1편 - 데이터 접근 핵심 원리
save() 호출시 키 중복예외로 복구를 시도하는 경우의 대안책
안녕하세요.스프링과 문제해결 - 예외처리, 반복에서 ExTranslatorV1Test.java 소스를 보면repository.save호출시 MyDuplicateKeyException예외가 발생하면random숫자를 더해서 복구를 합니다. 예외를 잘 다루줄 몰랐던 시절, 저는 save전에 findById를 통해 DB에 동일한 값이 있는지 확인하는 코드를 짜왔는데요. 위 두 방법의 장단점이 무엇인지 궁금합니다. 혹시 전자의 방식이 더 올바르다고 말할 수 있나요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
일대 다 중간테이블
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]안녕하세요! 혹시 다대다의 경우는 중간테이블을 두어 푸는 것이 실무에서 필수적이라 했는데, 일대 다의 경우에도 비즈니스 로직 분리:중간 테이블을 통해 비즈니스 로직(보상 분배, 순위 계산 등)을 별도로 관리함으로써, 엔티티 간의 복잡성을 줄입니다.데이터의 독립적 관리:과거 랭킹 기록, 보상 내역 등 변경하지 않아야 할 데이터를 독립적으로 저장하고 관리할 수 있습니다. 이런 이유로 중간테이블을 두기도 하나요? 예를 들어 사용자와 랭크 관계가 일대 다인 상황에서(사용자는 한 랭크만 참가 가능) 과거 정보들을 저장하기 위해 중간테이블을 두고 거기에 전적 같은 정보를 저장하고자 하는데 이런 경우 일대 다임에도 중간테이블을 놔두어 관리해도 되나요?
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
예외 분류와 문서화의 의미
안녕하세요. 강사님 강의내용을 좀 더 눈에 들어오게 만들고 싶어 아래와 같이 표로 정리했습니다. 두 가지 질문이 있습니다.질문1) 표로 분류한 것처럼 한 체크예외에 복구가능/복구불가 , 한 언체크예외에 복구가능/복구불가 분류가 가능한가요?체크예외복구 가능한 예외복구 불가능한 예외언체크예외복구 가능한 예외복구 불가능한 예외 질문2) 언체크예외 특징을 위 표로 정리를 했음에도 강의에서 문서화를 강조하신 이유를 파악하지 못했습니다.개발자가 개발당시 미래에 실행중에 어떤 런타임예외가 발생할 지 모르기 때문에 즉, 런타임예외 모든 경우의수를 예측하기 어렵기 떄문에 '처리'를 하지 못한다고 이해해도 될까요? 따라서 운영중에 마주하게 되는 런타임예외들을 매 순간마다 문서에 기록해두라는 말씀이신지 궁금합니다.
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
Rest 로그인 후 403 오류
Rest 방식 로그인 하였을 때 유저정보를 불러오지를 못합니다.로그인 하였을 때 로그 filerChainrestFilterrestcontroller@AuthenticationPrincipal 에 담긴 정보
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
내추럴 템플릿이 정확히 뭔 개념인가요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.내추럴 템플릿 기능이라는 것이 정확히 무엇인지 모르겠습니다.느낌은 파일을 직접 열기 할 때, html css 자바스크립트의 순수한 구조가 그대로 남겨진 것? 이라는 것 같은데 맞는지 모르겠습니다.
-
미해결코드로 배우는 스프링 웹 프로젝트 - Intermediate
로그인 처리 시 패스워드 null이 들어 가는 현상
강사님 코드 대로 로그인 처리 시 password가 null 이라 로그인 실패 합니다<security:authentication-manager> <security:authentication-provider user-service-ref="myUserDetailsService"> </security:authentication-provider> </security:authentication-manager>결국 검색을 통해 <security:authentication-manager> <security:authentication-provider user-service-ref="customUserDetailsService"> <!-- PasswordEncoder 추가 --> <security:password-encoder ref="passwordEncoder" /> </security:authentication-provider> </security:authentication-manager>안에 코드를 추가하니 정상으로 로그인 처리가 되었습니다의문점은 왜 강사님은 저 코드를 추가 하지 않아도 정상 적으로 로그인이 되는 건지 궁금합니다 제가 빠뜨린 코드가 있나 전부 체크를 해보았는데 그런 부분은 없었습니다
-
미해결스프링 핵심 원리 - 기본편
DIP, OCP
[질문 내용]관심사의 분리 영상에서 김영한 강사님께서 DIP를 지킨 것을 강조하고 있는데 제가 보았을 때는 DIP도 지키고 OCP도 지켜진 것을 확인하였습니다. 그러나 OCP도 지켰다는 것은 왜 얘기를 안 하시는지 궁금합니다.
-
해결됨실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
memberForm 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요. 저는 memberForm을 생성해서 뷰로 전송 -> 뷰에서 memberForm을 setter로 채움 -> 채운 memberForm을 post요청에 함께 전송으로 이해했습니다. 근데 create에서 받은 memberForm하고 createForm에서 받은 memberForm하고 다른 객체로 나옵니다.어디 부분이 잘못됐는지 알고싶습니다.
-
미해결스프링 핵심 원리 - 기본편
ReteDiscountPolicy의 discount 메소드 블록
[질문 내용]4분 50초 쯤에 할인계산하는 코드에서 return price * discountPercent / 100 부분을 저는 return price / discountPercent라고 하였는데 두 개 다 계산으로는 모두 같은 값이 나오는데 return price / discountPercent 이렇게 해도 상관없죠?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
타입 컨버터 질문있습니다.
안녕하세요.앞선 강의에서 @RequestParam, @ModelAttribute, @RequestBody, HttpEntity 같이 컨트롤러에서 다양한 파라미터를 사용할 수 있는 이유가 ArgumentResolver 때문이라고 배웠습니다.이 중에 @RequestBody와 HttpEntity를 처리하는 ArgumentResolver에서 Http 메시지 컨버터를 사용한다고 했는데 이 Http 메시지 컨버터가 타입 컨버터인건가요?또 @ModelAttibute, @RequestParam을 처리한는 ArgumentResovler는 DataBinder을 사용하는 것 같던데 이번 강의에서는 타입 컨버터를 사용하는 것 처럼 이야기를 하셔서 헷갈리네요..
-
미해결스프링 DB 1편 - 데이터 접근 핵심 원리
강의중에 하신 말씀이 궁금합니다. "우리가 직접 의존관계를 주입..."
안녕하세요. 강사님트랜잭션 문제해결 - 트랜잭션AOP적용 강의에서 하신 말씀에 질문이 있습니다. 07:20 이후에 나옵니다."물론 우리가 직접 의존관계를 주입해서 써도 되고요" 라는 말씀이 궁금합니다. 기본편에서 열심히 공부했던 개념이 나오는데요.스프링빈 구성방식직접호출(@Configuration, @Bean)자동호출(@ComponentScan, @Component)강의에서DataSource와 TxManager를 빈등록하는 방법으로 위 1번방식으로 진행했습니다.Proxy는 DataSource와 TxManager빈을 2번방식으로 주입받아서 진행된다고 설명하셨습니다.@Component public class TransactionProxy { private MemberService target; public void logic() { //트랜잭션 시작 TransactionStatus status = transactionManager.getTransaction(..); try { //실제 대상 호출 target.logic(); transactionManager.commit(status); //성공시 커밋 } catch (Exception e) { transactionManager.rollback(status); //실패시 롤백 throw new IllegalStateException(e); } } } 이후에 아래코드와 같이 1번 방식으로 직접 등록을 하려고 할 때, 의존관계를 직접주입해도 좋다라 말씀주신것 같습니다. (강의중 말씀: "물론 우리가 직접 의존관계를 주입해서 써도 되고요")//@Component 자동빈등록하지 않을거고 설정클래스에서 직접 수동등록할 예정 public class TransactionProxy { private MemberService target; public void logic() { //트랜잭션 시작 TransactionStatus status = transactionManager.getTransaction(..); try { //실제 대상 호출 target.logic(); transactionManager.commit(status); //성공시 커밋 } catch (Exception e) { transactionManager.rollback(status); //실패시 롤백 throw new IllegalStateException(e); } } } @TestConfiguration static class TestConfig { @Bean DataSource dataSource() { return new DriverManagerDataSource(URL, USERNAME, PASSWORD); } @Bean PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(dataSource()); } @Bean TransactionProxy txProxy() { return new TransactionProxy(transactionManager()); } }
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
중복 회원 예외 테스트를 Junit5버전으로 맞게 수정된건지 궁금합니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@Test public void 중복_회원_예외() throws Exception{ //given Member member1= new Member(); member1.setName("kim"); Member member2= new Member(); member2.setName("kim"); //when memberService.join(member1); //then assertThrows(IllegalStateException.class,()->{ memberService.join(member1); }); }중복 회원 예외 테스트에서 Junit5에선 @Test(expected)를 지원하지 않는 것 같아 assertThrows를 사용하는 방식으로 변경해야한다고 하여 변경했는데 올바른 방법인지 궁금합니다. (변경한 방식으로 테스트 케이스는 통과는 하였습니다.)
-
미해결Java/Spring 테스트를 추가하고 싶은 개발자들의 오답노트
영속성 객체 구분으로 인한 JPA와 Querydsl의 Projection 사용
지금은 간단한 예제라 엔티티에서 JpaRepository를 사용하여 데이터를 가공해서 가져온 후 도메인 객체로 매핑시켜 controller에 넘겨 controller에서 response 객체로 변환시켰습니다.만약 Projection을 사용하는 경우Projection에서 바로 controller 패키지 안의 response 패키지 객체로 접근하는 것은 어떻게 생각하시나요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
회원 등폭폼, 상품등록폼 질문
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.<form th:action="@{/items/new}" th:object="${form}" method="post"><form role="form" action="/members/new" th:object="${memberForm}" method="post">첫번째는 상품등록 폼의 action이 th태그로 사용된경우두번째는 회원등폭 폼의 action이 그냥 사용된경우입니다.상품,회원의 @getMapping createForm과 @postMapping create의 경로가 같기때문에(member/new, items/new) 저는 위의 2개의 form.html 에있는 action을 action=""으로 둘다 설정했는데 저렇게 따로 하는 이유가 있을까요 ? 제가 배운 기억으로는 경로가 같으면 action="" 이렇게 사용하면 처음 요청했던곳으로 다시 post요청한다고 알고있어서요
-
미해결
QueryDSL 관련 질문입니다.
@Getter @Setter @Entity @SuperBuilder @AllArgsConstructor @Table(name = "member") @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Member extends BaseUpdateEntity { @Id @GeneratedValue(generator = "uuid2") private UUID id; private String email; private String password; @Column(columnDefinition = "INT") @Enumerated(value = EnumType.ORDINAL) private MemberStatus memberStatus; } @Getter @Setter @SuperBuilder @MappedSuperclass @NoArgsConstructor @EntityListeners(AuditingEntityListener.class) public abstract class BaseUpdateEntity extends BaseEntity { @LastModifiedDate private LocalDateTime updatedAt; @LastModifiedBy private String updatedBy; } @Getter @Setter @SuperBuilder @MappedSuperclass @NoArgsConstructor @EntityListeners(AuditingEntityListener.class) public abstract class BaseEntity { @CreatedDate @Column(updatable = false) private LocalDateTime createdAt; @CreatedBy @Column(updatable = false) private String createdBy; } public Page<AuthInfoDto> searchList(AuthSearchRequestDto requestDto) { JPAQuery<AuthInfoDto> query = queryFactory.select(Projections.fields( AuthInfoDto.class, member.email, member.memberStatus.as("status"), member.createdAt )).from(member) .where(searchCondition(requestDto)); // 검색 조건 설정 long totalCount = query.fetchCount(); List<AuthInfoDto> authInfoList = this.getQuerydsl().applyPagination(requestDto.getPageable(), query).fetch(); return new PageImpl<>(authInfoList, requestDto.getPageable(), totalCount); }사용자 정보를 Pagination해서 출력하게끔 하려고 합니다.문제가 되는 부분은List<AuthInfoDto> authInfoList = this.getQuerydsl().applyPagination(requestDto.getPageable(), query).fetch();해당 코드 부분인데 단순히 query.fetch()를 해서 List를 추출하는 것은 되지만 Pagination을 적용하고자 하면 에러가 납니다.org.hibernate.query.SemanticException: Could not interpret path expression 'member.createdAt'에러 내용은 위와 같습니다.QueryDSL 관련 gradle 정보도 같이 첨부합니다.// QueryDSL implementation 'com.querydsl:querydsl-core:5.0.0' implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' implementation 'com.querydsl:querydsl-apt:5.0.0:jakarta' implementation 'jakarta.annotation:jakarta.annotation-api' implementation 'jakarta.persistence:jakarta.persistence-api' annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" annotationProcessor "jakarta.persistence:jakarta.persistence-api" annotationProcessor "jakarta.annotation:jakarta.annotation-api"혹시 뭐가 문제일까요?? 도와주세요.
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
localhost ui 화면이 연결이 안돼요
저번에 실행했을 땐 잘 연결됐는데 지금은 이렇게 사진처럼 연결되지가 않네요.... 왜 이런건가요..?서버도 실행한 상태에서 local 주소를 입력했는데 이렇게 된 상태입니다.혹시 몰라 서버를 실행했을 때 에러가 뜨는 부분들을 다 캡쳐했습니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
MemberServiceTest 이게 왜 틀리죠?
package jpabook.jpashop.service; import jpabook.jpashop.domain.Member; import jpabook.jpashop.repository.MemberRepository; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; //@ExtendWith(SpringExtension.class) //@SpringBootTest에 이미 정의됨.(중복) @SpringBootTest @Transactional class MemberServiceTest { @Autowired MemberService memberService; @Autowired MemberRepository memberRepository; @Test public void 회원가입()throws Exception{ //given Member member=new Member(); member.setUsername("kim"); //when Long savedId = memberService.join(member); //then Assertions.assertThat(member).isEqualTo(memberRepository.findOne(savedId)); } }junit 5 버전이라 이렇게 고쳤는데도 테스트에 실패합니다. setUsername은 구버전 MemberRepository에서 오류가 나서 Member의 name을 username으로 바꿨습니다.test/resources/application.yml에spring: logging.level: org.hibernate.SQL:debug이것도 넣어줬는데 안됩니다
-
미해결Practical Testing: 실용적인 테스트 가이드
@Value 관련 환경변수 주입 테스트코드 질문..
@ActiveProfiles("test") @SpringBootTest class CategoryServiceTest { @Autowired private CategoryService categoryService; @DisplayName("카테고리 목록들을 조회한다.") @Test void getAllCategories() { System.out.println("222222222222222222"); } }@Service @RequiredArgsConstructor public class KakaoApiService { @Value("${social.kakao.apikey}") private String kakaoApiKey; @Value("${social.kakao.redirect_uri}") private String kakaoRedirectUri; }위와 같이 코드가 있을때 테스트 코드를 실행시키면Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'kakaoApiService': Injection of autowired dependencies failed다음과 같은 에러가 발생하는데,, @SpringBootTest를 돌릴때 환경변수 주입을 못받아서 실패하는것 같은데 이럴 경우 어떻게 테스트를 진행해야할까요 ?? 전혀 관련 없는 서비스인데 에러가 터져서 진행이 안됩니다 ㅜㅜ..```ymlspring: profiles: default: local social: kakao: apikey: ${KAKAO_API_KEY} redirect_uri: ${KAKAO_REDIRECT_URI} jwt: secret: ${JWT_SECRET} access_expiration_time: 36000000 --- # 테스트 환경 spring: config: activate: on-profile: test h2: console: enabled: true datasource: url: jdbc:h2:mem:~/ChallengeApplication driver-class-name: org.h2.Driver username: sa password: jpa: hibernate: ddl-auto: create show-sql: true properties: hibernate: format_sql: trueyml은 전체는 아니지만 이렇게 구성되어 있습니다.환경 변수주입은 ChallengeApplication에 다 넣어놨는데, 이게 테스트코드를 돌릴시에는 ChallengeApplication가 도는게 아니라 Junit 하위에 있는게 돌아서 환경변수 주입이 안된게 돌아서 실행이 안되더라구요 .. 보통 어떤식으로 하시나요 ? ㅠㅠ
-
미해결스프링 시큐리티 완전 정복 [6.x 개정판]
RestAuthenticationToken의미 token의 의미
RestAuthenticaionToken 클래스를 만든 의미가 궁금하고 여기 시큐리티에서 token의 의미가 무엇인지 궁금합니다
-
미해결스프링 핵심 원리 - 기본편
SOLID 원칙
SOLID 5가지 원칙 중에 OCP 개방-폐쇄 원칙을 설명하는 도중 7:25 쯤에 private MemberRepository memberRepository = new MemoryMemberRepository(); 에서 JdbcMemberRepository() 객체 구현으로 변경할 시 private MemberRepository memberRepository = new JdbcMemberRepository(); 라고 나오는데 OCP의 원칙이 구현 객체를 변경하려면 클라이언트 코드를 변경해야 한다고 설명되어있습니다. 그런데 방금 변경된 코드에서 보면 private MemberRepository memberRepository 이 코드는 동일하게 되어있다는 것입니다. 도대체 무엇때문에 김영한 강사님께서 코드 변경 안하고 좀 안되지 않냐고 말씀하신지 알려주세요.