inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

묻고 답해요

173만명의 커뮤니티!! 함께 토론해봐요.

버퍼가 비워지는 시점

미해결

Kevin의 알기 쉬운 Spring Reactive Web Applications: Reactor 1부

안녕하세요. Backpressure의 Drop 전략에서 버퍼가 비워질 때까지 Emit된 데이터가 Drop이 된다는 것은 이해했습니다. 그런데 1번 데이터가 subscriber에게 전달되어서 처리가 되면 버퍼에 자리가 한 자리 비게 되는데 왜 데이터가 계속 Drop이 되는건가요? (코드 실습에서 onNext()함수가 호출이 되어도 255,256,257 ~ 1024까지 모두 드랍됨) | 1, 2 | <-------- 3 듣랍 | 2, |. <-------- 4 드랍 (여기서 왜 4번 데이터는 안들어가나요?) | 5, 6 | Buffer DROP-LATEST를 보면 | 1, 2 | <---- 3들어오는 중 버퍼 가득 차서 drop | 2, 4 | <------ 1번이 버퍼에서 나가고 한 자리가 비어서 4번이 들어와짐 이런식으로 동작을 하는데 Drop은 이렇게 동작하지 않는 것 같아 버퍼가 어떻게 동작하는지 궁금하여 질문드립니다.

  • java
  • spring
  • project-reactor
  • webflux
jhjikhsdsdw 댓글 1 좋아요 1 조회수 364

코틀린에서 builder 패턴은 사용하지 않나요?

미해결

실전! 코틀린과 스프링 부트로 도서관리 애플리케이션 개발하기 (Java 프로젝트 리팩토링)

강사 님께서는 객체를 인스턴스화 하실 때, 생성자를 사용하거나, 정적 팩토리 메서드를 사용하는 방식 2가지를 이용하셨는데 혹시 코틀린에서 builder 패턴을 사용하는건 어떻게 생각하시나요?? defalut 파라미터를 이용하고 naming을 통해 builder패턴 처럼 사용할 수 는 있겠지만 java에서 builder패턴을 통해 객체를 만들었던 것에 비하면 불편하다는 생각이듭니다. 조언 해주시면 감사하겠습니다.

  • java
  • spring
  • kotlin
  • spring-boot
  • 리팩토링
백엔드 주니어 개발자 댓글 2 좋아요 2 조회수 2379

레디스에서 락이 필요한 상황에 대하여

미해결

재고시스템으로 알아보는 동시성이슈 해결방법

안녕하세요, 강의를 보고 공부를하다 궁금한 점이 생겨 질문드립니다. 제가 예측한 강의 내용으로는, "경쟁 상태 예시(재고 수량)에 대하여 레디스 를 활용한다." 라고 예측 했습니다. 이에 대하여, "레디스는 싱글 스레드 기반이니깐, 락킹 없이 해당 작업이 가능할 것" 이라고 추측하였는데요, 그러나 제가 생각지 못한 레디스 lock 과 관련된 내용을 접하게 되어 신기하면서도 또 궁금한 부분이 생겨 질문드립니다. 레디스 락 전략이 사용되는 이유와 예시를 조금더 들어볼 수 있을까요? 혹은 이와 관련하여 추가적으로 공부해볼 수 있는 자료를추천해주시면 감사하겠습니다.

  • java
  • spring
  • 동시성
성연 댓글 1 좋아요 0 조회수 500

왜 commit할 때 status를 넣어줘야 하나요.

해결됨

스프링 DB 1편 - 데이터 접근 핵심 원리

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] status는 트랜잭션 설정, 상태에 관한 정보인데, 이미 transactionManager는 생성할 때 dataSource를 넣어줬고, 또 트랜잭션 동기화 매니저가 있기 때문에 어떤 커넥션을 닫아야 할 지 알고 있을 것 같습니다. 그럼 commit()할 때난 rollback()할 때 그냥 닫거나 롤백하면 될텐데, 왜 status가 필요한가요?

  • spring
  • mvc
  • spring-jdbc
궁금이 댓글 1 좋아요 0 조회수 449

PageableExecutionUtils.getPage 의 최적화 로직만 따로 뺀 count 메소드입니다.

해결됨

실전! Querydsl

갱신된 강의자료에도 나와 있듯이, fetchResult, fetchCount 등의 메소드는 deprecated 예정입니다. 또한 해당 메소드는 Page 타입을 반환하기 때문에 Page 타입을 직접적으로 조작해야 한다는 제약이 있습니다. 이걸 잘 쓰면 되는데, Page 의 시작번호 등 제약도 있어서 저는 회사에서 Page 를 따로 만들어서 사용하거든요. 그래서 search 메소드와 count 메소드는 항상 분리하고 있습니다. 2. 그런 점에서 count 만 최적화하는 로직만 베껴서 만든 최적화 메소드입니다. 실제로 count 구문을 실행하기 위한 메소드입니다. 필요에 따라서 public 으로 만들어도 될 것 같네요. // count 실행 메소드 private Long countByCond(MemberSearchCond cond) { return query .select(member.countDistinct()) .from(member) .where( usernameEq(cond.getUsername()), teamNameEq(cond.getTeamName()), ageGoe(cond.getAgeGoe()), ageLoe(cond.getAgeLoe()) ) .fetchOne(); } 최적화 로직을 베낀 메소드입니다. 스프링 데이터 JPA 는 아래 코드와 같이 page, size 값이 null 이 아니고, 적절한 범위에 있는지를 판단하여 isPaged 라는 분기를 만듭니다. 참고로 코드를 분석하면서 내린 뇌피셜이니 혹시 틀리다면 말씀해주세요. page 가 0 이 아니라 1 부터 시작하는 건 제 취향입니다. 회사에서 그렇게 쓰고 있거든요. 필요에 따라 0 부터 시작하도록 바꾸는 건 어렵지 않을 것 같습니다. public Long countByCondOptimization(List<?> content, MemberSearchCond cond, Long page, Long size) { boolean isPaged = page != null && size != null && page > 0 && size > 0; long offset = isPaged ? (page - 1) * size : 0L; long contentSize = content.size(); if (!isPaged || offset == 0) { if (!isPaged || size > contentSize) { return contentSize; } return this.countByCond(cond); } if (contentSize != 0 && size > contentSize) { return offset + contentSize; } return this.countByCond(cond); } 이렇게 하여 count 쿼리를 리스트 조회 쿼리와 분리하여 재사용성을 높이면서, 성능도 최적화할 수 있습니다. 감사합니다.

  • java
  • jpa
psam1017 댓글 1 좋아요 3 조회수 807

동적으로 Order 절 만드는 코드 공유합니다

해결됨

실전! Querydsl

강의에서는 Query DSL 4.x 버전이어서 제네릭 없는 예제 코드인 것 같은데, 제가 올리는 버전은 5.0 버전이어서 차이가 있음을 감안해주세요. 정렬 조건을 하나만 추가하는 코드입니다. 정렬 조건을 여러 개 추가하려면 반복문을 돌면서 JPAQuery 를 동적으로 확장해나가면 됩니다. // 페이징하는 메소드에서 사용 private Expression<? extends Comparable<?>> specifyMemberProperty(String prop) { prop = prop == null ? "" : prop.toLowerCase(); if (prop.equals("username")) { return member.username; } if (prop.equals("age")) { return member.age; } return member.id; } // 페이징하는 메소드 // ... .orderBy(new OrderSpecifier<>("desc".equalsIgnoreCase(dir) ? Order.DESC : Order.ASC, specifyMemberProperty(prop))) .fetch(); -- 저는 일단 이렇게 만들어봤는데, 다른 분께서 더 나은 코드, 더 빠른 코드가 있다면 저한테도 알려주세요. 감사합니다.

  • java
  • jpa
psam1017 댓글 0 좋아요 2 조회수 362

@ManyToOne Category parent 질문 있습니다.

미해결

자바 ORM 표준 JPA 프로그래밍 - 기본편

@ManyToOne @JoinColumn(name = "parent_id") private Category parent; @OneToMany(mappedBy = "parent") private List<Category> child = new ArrayList<>(); 안녕하세요. 위 코드에서 부모 쪽에 다대일 매핑 한 이유를 알고 싶습니다. 아니면 DB 테이블 안에서 부모 셀프 외래 키를 만들어서 조회할 때 이 외래 키를 참조하여 자식 카테고리들까지 같이 조회하게 만들었기 때문에 테이블에서 다는 parent_id니까 jpa에도 parent에 다를 준 건 가 싶기도 해서요 필드 명에 부모 자식이 있어서 부모는 하나고 자식은 여러 개인데 부모 쪽에 다로 돼있어서 헷갈리네요..

  • java
  • jpa
hoonseung 댓글 2 좋아요 0 조회수 569

Controller에서 BindingResult값을 유지한채로 @ExceptionHandler를 활용한 사용자 정의 예외를 처리하는법이 궁금합니다.

미해결

스프링 DB 1편 - 데이터 접근 핵심 원리

========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] Spring data jpa 를 활용하여 지금까지 배운 내용들을 총 합한 프로젝트를 만들어 보고 있는데 한가지 궁금증이 생겨 질문 드립니다. @ExceptionHandler을 사용하여 사용자정의 예외를 만들어 아이디 중복 예외를 처리하고싶은데 예외를 처리하는 과정에서 아이디가 중복일시 Controller의 BindingResult를 활용하여 아이디가 중복이면 View에 아이디가 중복이라는 정보를 표현하고싶어서 프로젝트를 코딩중에 Controller 부분에서 service단에서 throw한 사용자 정의 예외를 처리하려 하는데 try catch로 예외를 처리하는 순간 @ExceptionHandler를 사용하지 못하고 그렇다고 다시 예외를 던지자니 @ExceptionHandler에서 View에 관련된 Binding result의 값이나 ModelAttribute의 값을 보존해지 못하여 처리가 불가합니다. 이럴때 제일 좋은 방법이 무엇인지 알고싶습니다. Controller 코드입니다. @Controller @RequiredArgsConstructor @RequestMapping("/users") public class UserController { private final LoginService loginService; @GetMapping("/add") public String addForm(@ModelAttribute("userDto") UserDto userDto) { return "user/addUserForm"; } @PostMapping("/add") public String save(@Valid @ModelAttribute UserDto userDto, BindingResult bindingResult) { if (bindingResult.hasErrors()) { return "user/addUserForm"; } // if (loginService.signUpIdExists(userDto.getLoginId()) == false){ // bindingResult.reject("loginIdExists", "동일한 아이디가 존재합니다."); // return "user/addUserForm"; // } try { loginService.signUp(userDto); return "redirect:/"; } catch (UserIdExistsException e) { bindingResult.reject("loginIdExists", "동일한 아이디가 존재합니다."); return "user/addUserForm"; } } } Service 코드입니다. @Slf4j @Service @RequiredArgsConstructor public class LoginService { private final UserRepository userRepository; public User login(String loginId, String password) { return userRepository.findByLoginId(loginId).filter(m -> m.getPassword().equals(password)) .orElse(null); } public void signUp(UserDto userDto) { // if(signUpIdExists(userDto.getLoginId()) == false){ // throw new UserIdExistsException("이미 존재하는 아이디입니다."); // } try { Address address = new Address(userDto.getAddressDto().getZipcode(), userDto.getAddressDto().getStreetAdr(), userDto.getAddressDto().getDetailAdr()); User regisUser = new User(userDto.getLoginId(), userDto.getLoginName(), userDto.getPassword(), address); userRepository.save(regisUser); } catch (DataIntegrityViolationException e) { throw new UserIdExistsException("이미 존재하는 아이디입니다."); } } private boolean signUpIdExists(String loginId) { return userRepository.findByLoginId(loginId).isEmpty(); } } @ControllerAdvice 코드입니다. @Slf4j @ControllerAdvice public class ExceptionAdvice { @ExceptionHandler(UserIdExistsException.class) public ModelAndView userIdExHandler(UserIdExistsException e) { log.error("[userIdExistsException] ex", e); return new ModelAndView(); } } UserIdExistsException 코드입니다. public class UserIdExistsException extends RuntimeException{ public UserIdExistsException() { } public UserIdExistsException(String message) { super(message); } } 위 코드는 동작은 확인했지만 사실상 try catch 로 예외를 잡아버려서 @ExceptionHandler가 동작하지 않는 상태입니다. Entity의 아이디값에 unique 옵션을 걸어두어 아이디 중복이 일어날시 DataIntegrityViolationException에러가 일어납니다. 추가로 궁금한것 예외가 사실상 repository에서 터지는데 인터페이스에는 try catch가 권장되지 않는것으로 알고 통상 Service에서 에러를 처리하는것으로 알아 이렇게 코딩하였는데 이게 올바른건지 모르겠습니다. 예외를 발생시키는 지점을 repository로 옮기는것이 맞나요? Spring data jpa 는 알아서 Spring에 종속된 에러를 출력하는것으로 알고있는데 DataIntegrityViolationException에 속한 예외 두가지를 다른방법으로 처리하고싶으면 ErrorCode를 분석해 If문 으로 사용자 정의 예외를 만들어서 처리해야하나요? bindingresult를 사용하기 위해 어쩔수없이 예외를 throw하였더니 controller까지 예외가 전파되서 코드가 지저분해졌습니다. 이렇게 View에 특정한 값을 보내주어야할때 Controller에 예외를 throw 하지 않고 해결할수있는 좋은 방법이 있나요? 질문이 길고 지저분해서 죄송합니다. 나름 열심히 알아보고 코딩해보아도 잘 모르겠어서 질문남깁니다. 감사합니다.

  • spring
  • mvc
  • spring-jdbc
이성훈 댓글 2 좋아요 0 조회수 925

리소스 정리

해결됨

스프링 DB 1편 - 데이터 접근 핵심 원리

트랜잭션 매니저의 전체 동작 흐름에서 마지막에 '전체 리소스를 정리한다.' 라고 나와있는데 코드상으로 어디 부분에서 리소스 정리가 일어나는 건가요? 커밋이나 롤백을 하고 리소스 정리를 하는 코드가 내부에 존재하는 건가요?

  • spring
  • mvc
  • spring-jdbc
모깅 댓글 2 좋아요 1 조회수 358

예제 프로젝트 상에서의 Kafka 사용시 궁금한점

미해결

실습으로 배우는 선착순 이벤트 시스템

강의 잘 듣고 있습니다. 질문사항이 두개 있습니다. 1. 4강의 [문제점] 영상에서 쿠폰생성 10000개 요청으로 인해 mysql이 1분에 100개의 insert가 가능하다고 가정할 시 '주문생성/회원가입요청이 타임아웃 또는 10분뒤에 실행' 된다고 하셨는데요. 예제로 사용하신 Kafka 사용 예제에서는 Consumer 프로젝트도 어차피 API프로젝트와 같은 DB 를 바라보고 있으므로, 어차피 Kafka를 사용하여도 '주문생성/회원가입요청이 타임아웃 또는 10분뒤에 실행'되지 않나요? 왜 여쭤보냐면, 강의 내에서 Kafka 미사용시 주문생성/회원가입요청의 타임아웃 및 10분뒤 실행에 대한 해결책을 Kafka로 사용하셔서 문의드립니다. 2. 5강의 [Consumer 사용하기] 영상을 보면 API 프로젝트 Consumer 프로젝트가 별개로 존재합니다. 그러므로 API프로젝트의 테스트 케이스가 종료되어도 Consumer 프로젝트는 이미 Kafka로 100개의 데이터가 스트림으로 들어오는 상태이므로, 테스트케이스가 종료 되어도(즉, API프로젝트가 종료되어도) Cunsumer 프로젝트는 종료가 되지 않은 상태 이므로 100개의 쿠폰이 DB에 생성 이 되어야 하는게 아닌지요? 왜 여쭤보냐면, 강의 내에서는 API프로젝트가 종료되면 Consumer 프로젝트도 작업이 멈추는 현상이 있어서 문의드립니다.

  • java
  • docker
  • spring-boot
  • kafka
  • redis
김동건 댓글 2 좋아요 1 조회수 881

자바 인터페이스의 객체

해결됨

인터페이스는 일단 객체를 못만든다고 알고 있어요 근데 익명이너클래스를 이용해서 만드는 방법이 있던데 interface A{ abstract void abc(); } 이거를 A a = new A(){ public void abc(){.....} }; 이렇게 할 수 있던데 익명이너클래스에 인터페이스를 상속해서 abstract메서드를 오버라이딩 했기때문에 가능하다는 건 알겠는데 그러면 객체는 익명이너클래스의 객체 아닌가요...? 익명객체가 인터페이스A를 상속받았기때문에 다형적인 표현으로 A a 이렇게 표현이 가능한건가요? 저런 표현이 가능한가요? 참조변수 a는 인터페이스A 타입인 객체를 가리킨다는 뜻 아닌가요..? 근데 인터페이스는 객체를 못만든다고 배웠는데.. ㅠㅠㅠ 정말 이 부분이 이해가 안 갑니다 ㅠㅠㅠ 왜 객체를 인터페이스 타입으로 지칭하는지 ㅠㅠ

  • java
댓글 1 좋아요 0 조회수 315

커스텀 필터 등록 시, ApplicationFilterChain 에 등록

미해결

스프링 시큐리티

안녕하세요 강의 잘 듣고 있습니다! SecurityConfig에서 커스텀 필터 등록 시 @Bean 형식으로 필터객체를 생성하여 등록하면 ApplicationFilterChain에 등록되는게 맞는걸까요? Bean 만 선언한다면 ApplicationFilterChain 에 등록되고 addFilter(customFilter) 를 추가해주면 ApplicationFilterChain 리스트에도 등록되고 SecurityFilterChain 에도 등록이 됩니다. 문제는 제가 만든 커스텀 필터는, 특정 URL 에서는 동작 안하게끔 구현하고 싶은데 @Bean으로 등록했기 때문에 ApplicationFilterChain에 등록되어 어떤 요청이 들어오든 동작하는 게 문제입니다. @Bean 방식이 아닌 addFilter(New CustomFilter()) 로 하면 SecurityFilterChain에만 등록되긴 하는데 CustomFilter 는 스프링 컨테이너에 등록이 안되기 때문에 다른 Resource 객체들을 주입받지 못하는 상황입니다. 결론은 ApplicationFilterChain에는 추가 안하고 SecurityFilterChain에만 커스텀 필터를 추가하고 싶은데 New 방식 말고는 없는 것인지가 궁금합니다!

  • java
  • spring-boot
  • spring-security
mindecco 댓글 1 좋아요 0 조회수 794

Test 오류 발생 원인이 무엇인지 잘 모르겠습니다.

미해결

스프링 DB 1편 - 데이터 접근 핵심 원리

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.support.TransactionTemplate; import java.sql.SQLException; /** * 트랙잭션 - @Transactional AOP */ @Slf4j //final이 붙거나 @NotNull 이 붙은 필드의 생성자를 자동 생성해주는 롬복 어노테이션 public class MemberServiceV3_3 { private final MemberRepositoryV3 memberRepository; public MemberServiceV3_3( MemberRepositoryV3 memberRepository) { this.memberRepository = memberRepository; } @Transactional //이 메소드를 호출할 때, 트랙잭션을 걸고 시작하겠다는 의미. // 성공하면 커밋 실패하면 롤백을 한다. public void accountTransfer(String fromId, String toId, int money) throws SQLException { bizLogic(fromId, toId, money); } private void bizLogic(String fromId, String toId, int money) throws SQLException { Member fromMember = memberRepository.findById(fromId); Member toMember = memberRepository.findById(toId); memberRepository.update(fromId,fromMember.getMoney()- money); validation(toMember); memberRepository.update(toId,toMember.getMoney()+ money); } private static void validation(Member toMember) { if(toMember.getMemberId().equals("ex")){ throw new IllegalStateException("이제 중 예외 발생. 테스트 위해 만듦"); } } } 이것이 원본 코드이고 package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.sql.SQLException; import static hello.jdbc.connection.ConnectionConst.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * 트랜잭션 - @Transactional AOP */ @Slf4j @SpringBootTest //스프링테스트 어노테이션이 있으면 이 테스트에서 //스프링부트가 이 테스트에서 스프링 컨테이너를 만들고 필요한 스프링 빈을 전부 등록하고 스프링 빈에 대한 의존관계 주입도 받을 수 있게 된다 class MemberServiceV3_3Test { public static final String MEMBER_A = "memberA"; public static final String MEMBER_B = "memberB"; public static final String MEMBER_EX = "ex"; @Autowired // 의존관계 주입을 받아서 사용한다. private MemberRepositoryV3 memberRepository; @Autowired private MemberServiceV3_3 memberService; @TestConfiguration static class TestConfig{ @Bean DataSource dataSource(){ return new DriverManagerDataSource(URL,USERNAME,PASSWORD); } @Bean PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource()); } @Bean MemberRepositoryV3 memberRepositoryV3(){ return new MemberRepositoryV3(dataSource()); } @Bean MemberServiceV3_3 memberServiceV3_3(){ return new MemberServiceV3_3(memberRepositoryV3()); } } @AfterEach void after() throws SQLException { memberRepository.delete(MEMBER_A); memberRepository.delete(MEMBER_B); memberRepository.delete(MEMBER_EX); } @Test @DisplayName("정상 이체") void accountTransfer() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberB = new Member(MEMBER_B, 10000); memberRepository.save(memberA); memberRepository.save(memberB); //when memberService.accountTransfer(memberA.getMemberId(), memberB.getMemberId(), 2000); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberB = memberRepository.findById(memberB.getMemberId()); assertThat(findMemberA.getMoney()).isEqualTo(8000); assertThat(findMemberB.getMoney()).isEqualTo(12000); } @Test @DisplayName("이체중 예외 발생") void accountTransferEx() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberEx = new Member(MEMBER_EX, 10000); memberRepository.save(memberA); memberRepository.save(memberEx); //when assertThatThrownBy(() -> memberService.accountTransfer(memberA.getMemberId(), memberEx.getMemberId(), 2000)) .isInstanceOf(IllegalStateException.class); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberEx = memberRepository.findById(memberEx.getMemberId()); //memberA의 돈이 롤백 되어야함 assertThat(findMemberA.getMoney()).isEqualTo(10000); assertThat(findMemberEx.getMoney()).isEqualTo(10000); } } 이것이 테스트 코드입니다. 원본 코드는 따로 수정하지 않았고 테스트 코드만 가져와서 사용했는데 왜 오류가 발생하는지 잘 이해가 안됩니다 설명 부탁드립니다. 오류는 다음과 같이 나옵니다 Execution failed for task ':test'. > No tests found for given includes: [hello.jdbc.service.MemberServiceV3_3Test.AopCheck](--tests filter) * Try: > Run with --stacktrace option to get the stack trace. > Run with --info or --debug option to get more log output. > Run with --scan to get full insights. > Get more help at https://help.gradle.org. Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. For more on this, please refer to https://docs.gradle.org/8.2.1/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. BUILD FAILED in 577ms 4 actionable tasks: 1 executed, 3 up-to-date 설명 부탁드립니다

  • spring
  • mvc
  • spring-jdbc
blackhole124 댓글 2 좋아요 0 조회수 708

MemberServiceV3_3 테스트 코드 질문 있습니다.

미해결

스프링 DB 1편 - 데이터 접근 핵심 원리

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 위는 MemberServiceV3_3 코드의 @Transactional를 사용하는 메소드 부분이고 아래는 MemberServiceV3_3Test 코드입니다. package hello.jdbc.service; import hello.jdbc.domain.Member; import hello.jdbc.repository.MemberRepositoryV3; import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.context.TestConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.datasource.DriverManagerDataSource; import org.springframework.transaction.PlatformTransactionManager; import javax.sql.DataSource; import java.sql.SQLException; import static hello.jdbc.connection.ConnectionConst.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; /** * 트랜잭션 - @Transactional AOP */ @Slf4j @SpringBootTest //스프링테스트 어노테이션이 있으면 이 테스트에서 //스프링부트가 이 테스트에서 스프링 컨테이너를 만들고 필요한 스프링 빈을 전부 등록하고 스프링 빈에 대한 의존관계 주입도 받을 수 있게 된다 class MemberServiceV3_3Test { public static final String MEMBER_A = "memberA"; public static final String MEMBER_B = "memberB"; public static final String MEMBER_EX = "ex"; @Autowired // 의존관계 주입을 받아서 사용한다. private MemberRepositoryV3 memberRepository; @Autowired private MemberServiceV3_3 memberService; @TestConfiguration static class TestConfig{ @Bean DataSource dataSource(){ return new DriverManagerDataSource(URL,USERNAME,PASSWORD); } @Bean PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(dataSource()); } @Bean MemberRepositoryV3 memberRepositoryV3(){ return new MemberRepositoryV3(dataSource()); } @Bean MemberServiceV3_3 memberServiceV3_3(){ return new MemberServiceV3_3(memberRepositoryV3()); } } @AfterEach void after() throws SQLException { memberRepository.delete(MEMBER_A); memberRepository.delete(MEMBER_B); memberRepository.delete(MEMBER_EX); } @Test @DisplayName("정상 이체") void accountTransfer() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberB = new Member(MEMBER_B, 10000); memberRepository.save(memberA); memberRepository.save(memberB); //when memberService.accountTransfer(memberA.getMemberId(), memberB.getMemberId(), 2000); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberB = memberRepository.findById(memberB.getMemberId()); assertThat(findMemberA.getMoney()).isEqualTo(8000); assertThat(findMemberB.getMoney()).isEqualTo(12000); } @Test @DisplayName("이체중 예외 발생") void accountTransferEx() throws SQLException { //given Member memberA = new Member(MEMBER_A, 10000); Member memberEx = new Member(MEMBER_EX, 10000); memberRepository.save(memberA); memberRepository.save(memberEx); //when assertThatThrownBy(() -> memberService.accountTransfer(memberA.getMemberId(), memberEx.getMemberId(), 2000)) .isInstanceOf(IllegalStateException.class); //then Member findMemberA = memberRepository.findById(memberA.getMemberId()); Member findMemberEx = memberRepository.findById(memberEx.getMemberId()); //memberA의 돈이 롤백 되어야함 assertThat(findMemberA.getMoney()).isEqualTo(10000); assertThat(findMemberEx.getMoney()).isEqualTo(10000); } } 저는 지금까지는 원본 코드와 테스트 코드가 따로 따로라고 생각했습니다. 근데 강의에서 원본 코드의 @Transactional을 사용 했을 때와, @Transactional을 주석 처리해 원본 코드를 수정했을 때. 테스트 코드의 결과가 다르게 변하더라구요. 이런 결과가 왜 발생하는건가요? 테스트 코드는 원본 코드에 영향을 받는건가요? 만약, 영향을 받는다면 어떤 범위까지 영향을 받는건가요? 설명 부탁드립니다!

  • spring
  • mvc
  • spring-jdbc
blackhole124 댓글 1 좋아요 0 조회수 467

여러 패키지들 does not exist 오류

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

안녕하세요 김영한님! 강의 아주 잘 듣고있습니다!! 현재 김영한님 첫번째 강의를 다 듣고 저 혼자 만들어보고 싶은게 생겨서 만드는중인데요 현재 제가 군대에 있어서 사지방에서 코딩을 하느라 인텔리제이를 사용하지 못하고 깃허브에서 제공하는 codespaces와 gitpod을 사용하여 vscode 환경에서 코딩하는 중입니다. 근데 jpa의 JpaRepository나 lombok 혹은org.springframework.boot.autoconfigure.SpringBootApplication 이런 패키지들이 계속 does not exist라고 뜹니다. 김영한님꺼 따라할때는 잘 됐는데 이제 제가 혼자서 만들고 싶은거 만드려니 확실하지도 않고 실행도 잘 안돼서 패키지를 못읽는건지도 잘 모르겠습니다. 현재 build.gradle에 의존성도 다 넣어있고 vscode의 패키지 설치에도 java extention pack, lombok, spring extention pack또 다 깔았습니다. 당연 재설치도 해보았구요! 구글링을 지금 며칠째 하고있는데 도저히 안되서 여기에 질문 올려봅니다... springboot version : 3.1.3 jdk version : 17

  • java
  • spring
  • mvc
  • springboot
  • pleasehelpme
  • 군대
이정환 댓글 3 좋아요 0 조회수 3648

jdbc:h2:tcp://localhost/~/test로 연결시 오류가 발생합니다

미해결

스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] 여기에 질문 내용을 남겨주세요. 최초로 jdbc:h2:~/test로 연결을 실행 한 뒤 ~/ test.mv .db 파일 생성을 확인하였습니다. 그러고 영한님께서 말씀해주신 대로 jdbc:h2:tcp://l ocalhost/~/test 로 연결했더니 다음과 같은 오류가 발생하네요.. 해결방안 답변해주시면 감사하겠습니다. 참고로 h2 버전은 강의와 같은 버전을 사용하였습니다. +) 추가로 삭제 후 동일버전, 하위버전으로 재설치도 해보았는데 여전히 같은 오류가 발생합니다.

  • java
  • spring
  • mvc
  • spring-boot
djqwkfj43u 댓글 2 좋아요 0 조회수 2181

커넥션과 세션의 관계, 세션과 트랜잭션의 관계가 궁금합니다.

미해결

스프링 DB 1편 - 데이터 접근 핵심 원리

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 스프링 DB 1편 트랜잭션 이해 파트에서 질문입니다. "애플리케이션에서 DB 트랜잭션을 사용하려면 트랜잭션을 사용하는 동안 같은 커넥션을 유지해야한다. 그래야 같은 세션을 사용할 수 있다" 여기서 세션의 개념이 정확히 이해가 가지 않아 질문드립니다. 찾아본 결과 하나의 커넥션에는 여러 개 세션이 존재할 수도, 아예 없을 수도 있다고 하고, 세션은 전달된 SQL이 실행되는 하나의 논리적 단위라고 합니다. 강의 설명에 따르면 같은 세션을 유지해야만 트랜잭션이 하나의 단위로 처리되기 때문에 이를 위해 같은 커넥션을 사용해야 한다고 이해했습니다. 그렇다면 같은 커넥션을 사용하는 것을 보장했을 때 항상 같은 세션을 사용하는 것도 보장되는 것인가요? 한 커넥션이 여러 세션을 사용하는 경우는 어떤 경우인가요? 여러 세션을 사용하게 되면 여러 세션에서 여러 개의 트랜잭션이 실행될 수 있는 것인가요?

  • spring
  • mvc
  • spring-jdbc
지강훈 댓글 1 좋아요 0 조회수 499

복합키 끼리의 매핑 질문 드립니다.

해결됨

자바 ORM 표준 JPA 프로그래밍 - 기본편

안녕하세요. 현재 JPA강의를 통해 회사내 프로젝트중인 직장인 입니다. 실무 중에 강의의 복합키 매핑과는 조금 다른 내용이 있어 며칠을 고민하다 문의 드립니다. 각각 복합키를 가진 두 개의 테이블 이 있습니다. 두 테이블은 code라는 공통 컬럼이있고 다대일관계로 매핑 을 구성하려고 합니다. @EmbeddedId관계 를 이용해 구성하려고 합니다. code 컬럼만 매핑시키는 방법을 찾지 못해 문의 남겨드립니다. 현재 문제의 테이블입니다.(회사프로젝트 테이블이라 자세히 올려드리는 못하는 점 양해 부탁드립니다.) Company Table은 code, biznumber 두 개의 pk로 구성돼 있습니다. Contract Table 역시 code, module 두 개의 pk로 구성돼 있습니다. 저는 두 테이블에서 code라는 컬럼만 갖고 다대일 매핑 을 구현하고 싶습니다. 즉 복합키를 각각 가진 두 개의 테이블에서 각각 하나의 컬럼만을 이용해 다대일 매핑을 구현하고 싶습니다. 제가 에러 내용과 과정을 올리고싶은데 회사코드라 올리면 문제가 생길까 싶어 이렇게 말로 표현드려 죄송합니다.

  • java
  • jpa
차재욱 댓글 2 좋아요 1 조회수 979

@Transaction 적용 시 수동 빈 등록 관련 질문

해결됨

스프링 DB 1편 - 데이터 접근 핵심 원리

[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] @Transaction을 사용 시, 스프링 AOP가 적용되어야 하기 때문에 테스트 코드에서는 @SpringBootTest와 함께 트랜잭션 적용에 필요한 다양한 객체를 수동으로 등록하고 적용하는 법을 배웠습니다. (PlatforTransactionManager, DataSource 등) 그러면 테스트 환경이 아닌 서비스 로직에서 @Transaction을 사용할 경우에는 강의에서 진행한 수동 빈 등록 절차를 거치지 않아도 되는 건가요? @Transcation을 썼을 때 트랜잭션에 필요한 빈들을 자동으로 등록한다는 내용이 이 뜻인건지 궁금합니다.

  • spring
  • mvc
  • spring-jdbc
cho766 댓글 1 좋아요 0 조회수 259

스프링 사용 관련 궁금한 사항이 생겨 질문드립니다

미해결

토비의 스프링 부트 - 이해와 원리

스프링 사용 관련 궁금한 사항이 생겨 질문드립니다 토비님 안녕하세요~ 오늘 아침에 웹프로그램 개발하다 갑자기 궁금한 사항이 생겼습니다 1. MVC 컨트롤러 를 이용 할 때 보안상 문제로 get을 사용하지 않고 post 만 작성 하는게 맞는것인지 웹프로그램을 개발 할 때 브라우저 url 에는 파라미터가 전혀 안보이는것이 보안상 최선인지 궁금합니다 토비님도, 스프링 mvc 를 이용해서 개발 하실때 모두 post 방식으로 request 를 하시는지 궁금합니다 (간혹 금융권 사이트에서는 url 부분에 파라미터가 안보였던거 같아서요.. ) 2. 네이버/카카오/유튜브 open API 등을 누가나 사용 할 수 있는데요 나쁜 사용자가 악의적인 의도를 갖고 마구 request 호출 을 할 경우 서버 트랙픽을 방어 하려고 하면 스프링의 어느 기술을 이용해서 막을 수 있을 까요? 3. 스프링 프레임웍 안에서 뷰(프론트) 부분에 JSP / 타임리프 / php / react / vue 동시에 여러가지를 함께 쓸 수가 있나요? 감사합니다. 수고하세요

  • spring
  • spring-boot
  • spring-jdbc
주아아빠 댓글 1 좋아요 0 조회수 350

인기 태그

인프런 TOP Writers

주간 인기글