묻고 답해요
169만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 데이터 JPA
안녕하세요! Exception 관련 질문드립니다!
안녕하세요! 6월 방학부터 개학한 오늘까지 김영한님의 모든 강의를 들으며 많은 깨달음을 얻고 실력을 키웠습니다. 먼저, 정말 좋은 강의를 해주셔서 감사하다는 말씀을 드립니다! 제가 질문드리고 싶은건 NoResultException입니다! JpaReopsitory<T,ID>를 상속받는 레포지토리는 Member findByUsername(String username) 를 하고 memberRepository.findByUsername("DB에 없는 username") 을 할시에 null이 들어가면서 exception이 터지지 않는데 MemberRepository.java public Member findByUsernmae(String username) { return em.createQuery("select m from Member m where m.username=:username", Member.class) .setParameter("username", username) .getSingleResult();} memberJpaRepository.findByUsername("DB에 없는 값")을 할시에는 Exception이 터집니다. 먼저, Repository 내에서 NoResultException이 터지고 Repository에서 나갔을때는 EmptyResultDataAccessException이 터지는거에 궁금했었는데 이건 방금 강의에서 말씀해주셔서 아! 하고 알았습니다. 하지만, JpaRepository를 상속받은 레포지토리는 같은 쿼리를 날리지만 어떤 원리로 exception이 터지지 않고 null이 들어가는지 궁금합니다! 혹시, JpaRepository인터페이스를 구현한 클래스에서 Exception을 잡은다음에 null로 뿌려주는것일까요? 감사합니다!
-
미해결스프링 핵심 원리 - 기본편
핵심원리까지 완강 후 방향에 대해 의견 여쭙니다
안녕하세요 강사님! 학원에서는 스프링 원리에 대해서는 안알려주고 무작정 이렇게 코드 짜는거다라고 알려줘서 너무 답답했었는데 강사님 강의를 듣고 속이 뻥~! 뚫렸습니다! 이론강의를 정말 안좋아하는데 강사님 수업은 너무 재밌고 다음 내용이 궁금해서 밤새가면서 봤네요 :D (입문 강의 때는 완전히 이해가 안가더라도 일단 입문을 학습하는게 좋다는 강사님 말만 믿고 따라했더니 정말 되더라구요) 핵심원리 수업을 듣고나서 스프링이 이런거구나 이래서 이 코드를 작성했던거구나 하고 이해는 가는데 다른 사람에게 설명하라고 하면 그정도 실력은 안되는 것 같아 고민입니다. 이걸 어떻게 활용을 해야할지도 문제구요. 사실 제가 학원에서 배웠던 스프링이랑 비슷하면서도 굉장히 다르다는 생각을 합니다. 현재 상황에서 HTTP와 MVC를 듣고 JPA 로드맵으로 넘어갈 지, 핵심원리를 한번 더 복습하고 핵심원리에 대해 완전히 익히고 넘어가야할 지 정말 고민이 됩니다. 이후 강의를 듣다보면 이번 강의에서 놓친 부분들까지 체계를 잡게 될지가 의문스러운 것 같습니다. 어떻게 해야할까요?
-
미해결스프링 핵심 원리 - 기본편
자동등록과 수동 등록의 공존
안녕하십니까 강사님!! 수업 너무 재밌게 잘 듣고있습니다! 수업을 듣다 궁금한점이 생겨 질문 남깁니다. 요번 강의에서 예시코드로 DiscountPolicyConfig 클래스를 만들고 수동으로 Bean에 주입이 되었는데요, 이때 자동 등록하는 Configuration가 discountPolicyConfig의 Configuration까지 bean으로 주입해버릴 것 같은데, 이 부분은 어떻게 해결할 수 있을까요? 이전에 배운 excludeFilters를 사용하면 Configuration이 있는 모든 클래스의 의존성 주입을 막게돼서 discountPolicyConfig에서 수동으로 주입하는 메서드들이 작동하지 않을것 같네요... 배웠던 것 같기도한데, 헷갈리는 부분이 있어 질문 드립니다!! 항상 좋은 강의 감사합니다 :)
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
궁금증이 있어 질문드립니당!
안녕하세요 ! 강의 잘듣고있습니다 제가 궁금한건 처음 강의에서는 http://localhost:8080/hello<-.html이 붙어 있지않아도 그냥 들어가졌지만 지금강의 에서는 http://localhost:8080/basic/hello-form.html 이런식으로 .html이 붙지않으면 에러페이지가 뜹니다 혹시 이유를 알수 있을까요 ?ㅠ
-
해결됨스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
비밀번호 관련 질문입니다.
로그인 예제를 진행하면서 비밀번호 암호화까지 진행해보고 싶었습니다. 그래서 구글링으로 스프링 시큐리티 기능에서 PasswordEncoder 기능만 살짝 달아서 적용해봤습니다. 그런데 생각해보니 프론트에서 HTTP로 비밀번호를 전송해서 서버 측에서 암호화를 진행하는 방식은 네트워크 상에서 해킹당하면 의미가 없는 거잖아요? 이런 건 HTTPS 적용하는 방법 외엔 적당한 해결책은 없나요?
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
타임리프 미사용시
만약 타임리프를 사용하지 않고도 BindingResult를 통해서 오류 검증사항을 프론트쪽으로 넘겨줄수 있나요? 아니면 이럴때는 다른 방법을 사용하나요?
-
미해결스프링 데이터 JPA
복잡한 통계쿼리도 JPA로 가능한가요?
기선님 쉽게 설명해주시는 강의를 보며 참 많은 도움이 되고있습니다. 실제 제가 만들고 있는 모델관 다르지만 질문하기 위해 예시를든다면 , 쇼핑몰을 예로 어떤 상품들이 있고 그것에 대한 판매가 이뤄진다고 가정할때 엔티티는 상품, 주문, 결제등이 있을수 있겠죠. 이때 '상품들의 월별 판매량'을 통계 내야 한다고 치고 --------------------------------------- 상품명 1월 2월 3월 4월 5월 ... 합 -------------------------------------- 상품A 20 15 4 7 8 104 상품B 1 1 10 2 1 25 ---------------------------------------- 이런식의 통계 쿼리를 짜야 할경우 JPA로 가능한지? QueryDSL 등을 써서라도 가능한지? 감이 안잡힙니다.
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
테이블 설계 관련 질문
프론트 엔드에서 전체 category를 조회해서, 화면에 카테고리를 선택할수 있도록 출력해주는 화면이 있고 유저가 게시글을 등록한다고 한다면 --- 1. 아래와 같이 Category 테이블에 모든 카테고리를 저장해 (init), 2. 이 리스트를 전달해주고, (미리 카테고리들은 정해져 있다고 할때, 추가도 할수 있겠지만) 3. user가 게시글을 등록할때 client가 입력한 category를 category table에서 찾아오고 4. 그 값을 기반으로 post와 postCategory에 저장해주는 방식이 되어야 하는거 같은데 (강의들중 어디에서 질문하는게 좋을지 약간 애매해서 여기에 글 올립니다.) ------ 이렇게 하는 방식이 맞을까요? 뭔가 동작 하게끔 할수 는 있는데 올바른 방법같지 않아서 영한님 다른강의들도 들어보면서 같이 몇일째 고민중인데 찜찜하고 명확하게 확신이 안섭니다. 카테고리 목록은 initService를 하나 만들어서 미리 저장해두었습니다. (강의에서 하신 initDb처럼) 답변주시면 감사드리겠습니다. 몇일째 해결이 안되요 ㅠㅠ post테이블의 CATEGORY_TAG는 삭제 예정입니다 public class Post { @Id @GeneratedValue @Column(name = "post_id") private Long id; private String title; @Lob private String desc; private int price; @Enumerated(EnumType.STRING) private Status status; @ManyToOne @JoinColumn(name = "account_id") private Account seller; @OneToOne(cascade = CascadeType.ALL) @JoinColumn(name = "post_category_id") private PostCategory postCategory; // old @Enumerated(EnumType.STRING) private CategoryTag categoryTag; /*@OneToOne @JoinColumn(name = "category_id") private Category category;*/ public Post(String title, Account seller){ this.title = title; this.seller = seller; status = Status.NEW; } // old public Post(String title, String desc, int price, CategoryTag categoryTag, Account seller){ this.title = title; this.desc = desc; this.price = price;// @Converter this.categoryTag = categoryTag; this.seller = seller; status = Status.NEW; seller.addPost(this); } public Post(String title, String desc, int price, Account seller){ this.title = title; this.desc = desc; this.price = price;// @Converter this.postCategory = postCategory; this.seller = seller; status = Status.NEW; seller.addPost(this); } //== 연관관계 메서드 ==/ public void setSeller(Account seller) { this.seller = seller; seller.addPost(this); } //== 바즈니스 로직 ==// // old public static Post post(String title, Account seller, CategoryTag categoryTag){ Post post = new Post(title, seller); post.setCategoryTag(categoryTag); return post; } public void setPostCategory(PostCategory postCategory){ this.postCategory = postCategory; postCategory.setPost(this); }} @Entity@Setter@Getterpublic class PostCategory { @Id @GeneratedValue @Column(name = "post_category_id") private Long id; @OneToOne(mappedBy = "postCategory") private Post post; @OneToOne @JoinColumn(name = "category_id") private Category category;} @Entity@Getter@Setter@NoArgsConstructor(access = AccessLevel.PROTECTED)public class Category { @Id @GeneratedValue @Column(name= "category_id") private Long id; @Enumerated(EnumType.STRING) @Column(unique = true) private CategoryTag categoryTag; public Category(CategoryTag categoryTag){ this.categoryTag = categoryTag; }} @PostMapping("/new2")public PostResponseDto postV2(@RequestBody PostRequestDto postRequestDto, @ApiIgnore HttpSession session){ Account account = getSessionCheckedAccount(session); Post post = new Post(postRequestDto.getTitle(), postRequestDto.getDesc(), postRequestDto.getPrice(), account); Category category = categoryJpaRepository.findByCategoryTag(postRequestDto.getCategoryTag()); PostCategory postCategory = new PostCategory(); postCategory.setCategory(category); post.setPostCategory(postCategory); Long postId = postService.post(post); return new PostResponseDto(postId);}
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
.findAny(); 입력후 에러
@Overridepublic Optional<Member> findByName(String name) { store.values().stream() .filter(member -> member.getName().equals(name)) .findAny(); // 이거 오류왜나지} 입력후 missing return statement 에러가 납니다. findAny() 함수가 애초에 null일때 처리하는 함수라고 들었는데 return 타입이 missing이라니 뭐가 문제인지 모르겠습니다.
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Regions 필드의 값이 추가되는 동작방식이 궁금합니다!
강의를 통해 열심히 배우고 있는 학생입니다 이번에 여쭤보고싶은게 있어 질문했습니다. 다중 체크박스에서 서울과 부산을 선택해서 상품 수정시 폼 데이터 전송 방식까지 확인 했습니다. 또한Item 클래스에서 regions 필드는 List 타입으로 선언되어 있으며 @Data 애노테이션으로 롬복이 getter sertter 등을 자동 생성해준다고 학습했습니다. 여기서 궁금증이 생겼습니다. 컨트롤러에서 @ModelAttribute를 사용할 시 Item 타입의 객체를 생성하고 객체의 프로퍼티까지 셋팅해주며 그 방식이 폼 데이터로 넘어온 name 값으로 setter를 호출한다고 알고있는데 list 타입으로 선언한 regions의 setter호출시 자동으로 값을 넣어주는 기능을 하는건가요?? Item 객체의 regions 필드에 Seoul, Busan과 같은 값이 어떻게 추가 되었는지 궁금합니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
객체로 Http 요청을 받을 때
객체안의 변수와 json타입으로 들어올때 변수 이름이 같아야만 사용할 수 있는건가요???
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
Controller Exception Advice domain별 패키지에서 구성
Exception의 경우 domain마다 다양하게 구성되는 것 같은데 한곳에서 모든 도메인의 익셉션을 핸들링하는것 보다 각 도메인 별로 Exception 패키지를 둬 해당 패키지에 도메인별 익셉션 정의 + 도메인별 advice 공통 익셉션의 경우 public? 패키지에서 관리 이런식으로 구성을 해 관리하는게 더 좋아보이는데, 영한님의 의견이 궁금합니다. + 영한님은 패키지 관리를 어떤식으로 하시는지 + 이런 구조를 효과적으로 잡는데 있어 참고할만한 서적이 있는지 답변주시면 감사드리겠습니다.
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
defaultValue 질문입니다
@RequestParam(required = false, defaulValue = "-1") int age 일 때 age는 int 자료형인데 defaultValue = "-1" 인데 이럴 경우 숫자 -1인지, 문자 -1 인지 구별할 방법이 없는데 그 변수의 자료형에 맞게 "@@@" 안의 값이 설정되는건가요 ?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
요청, 응답 시 annotaion, httpEntity 사용 관련
요청, 응답시 관련해서 몇가지 질문 사항이 있습니다. 1. 응답코드를 주고자 할때 , 어노테이션 // 리스폰스 엔티티 둘다 사용가능한데 어떤 경우에 어떤걸 사용하는게 더 좋은지 2. 마찬가지로 헤더 값이 필요한경우 어노테이션 // 리퀘스트 엔티티 둘다 사용가능한데 어떤 경우에 어떤걸 사용하는게 더 좋은지 3. modelAttribute 사용시 dto로 parameter들을 받을때 dto니까 setter를 그냥 사용하는게 좋은지아니면 entity처럼 setter를 사용하지 않고 필드 억세스 하도록 만들어 주는게 좋은지, 그렇다면 왜 그런지 3가지가 궁급합니다. 강의들 다시 복습하면서 요즘 이것저것 여쭤보는데 항상 친절히 답변해주셔서 감사합니다.
-
미해결스프링 핵심 원리 - 기본편
@AllArgsConstructor, @RequiredArgsConstructor 사용금지를 권하는 글을 보았습니다.
https://kwonnam.pe.kr/wiki/java/lombok/pitfall파라미터 선언 순서 변경에 따른 생성자에서 파라미터 순서로 변화로 인해 발생할 수 있는 치명적인 오류를 사전에 방지하기 위해 @AllArgsConstructor, @RequiredArgsConstructor 의 사용은 자제하는 것을 권하던데Spring 프로젝트에서도 마찬가지로 적용되는 경우가 있을까요?예를 들어, 컨테이너 안에 같은타입의 빈이 여러개인 충돌 문제가 아니라하나의 클라이언트에서 같은 타입의 의존성을 두개 주입을 요구할 경우가 있을까요? private final DiscountPolicy discountPolicyFirst; private final DiscountPolicy discountPolicySecond; 이렇게 될 경우, 순서가 중요할거 같지만@Qulifier 같은 방식을 사용하지 않으면 같은 의존성만 주입될거 같고@Qulifier를 사용하면 의존성을 요구하는 필드의 순서 문제가 자동으로 해결될거 같기도 하구요아니면 현실적으로 이런 방식을 쓰기보단Map이나 List를 사용하여 자체적으로 로직을 만들어 상속하는 같은 계열의 빈을모두 가져와서 선택적으로 여러개의 의존성을 사용하는게 맞을까요?추가적으로 궁금한 점이 있습니다.@Qualifier를 사용하여 같은 타입의 빈이 두개 이상 있을때 선택할 수 있다고 하셨는데@RequiredArgsConstructor를 사용한 경우엔 자동으로 생성자를 만들어줘서 @Qualifier를 사용하여 의존성을 주입할 수 없는건가요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
HTTP RESTAPI 경로에 식별자 관련
HTTP API 경로에 entity의 식별자를 넣어 사용하는게 추세라고 하셨는데 -------- @GetMapping("users/{userId}/posts/{postId}") 라고 할때, mvc2 강의에서 user의 정보는 탈취 당하고 악용될 수 잇으므로 session 을 통해 user의 info를 받아와 사용한다고 말씀하셨습니다 ------ 그러면 user에 대한 경로는 다 없애고 session을 통해 정보를 받아와서 사용하고 그 외 다른것은 저렇게 식별자를 통해서 사용해서 api 경로를 매핑하면 될까요? REST API case에서 자신이 등록한 게시글만 조회하는 api의 경우 ----- @GetMapping("/posts/{postId}") public post(HttpSession session, @PathVariable Long postId){ Long userId = (Long) session.getAttribute(LOGIN_ACCOUNT); } 이런식으로 사용하면 될까요? ------- 추가적으로 위처럼 적용한다고 하면, 자신이 등록한 post를 api 조회하는 경로와, 전체 post에서 어떤 post를 조회하는 api의 경로가 같게 되는데여기서 또 문제가 있는 것 같습니다. 위 처럼 사용시 자신이 등록한 post들 전체 조회 api => "/posts" 전체 post 조회 api 또한 => "/posts" 어떤 방식으로 접근하는게 좋은지 답변주시면 감사드리겠습니다.
-
미해결실전! 스프링 데이터 JPA
결과 리스트의 size() vs count 쿼리
count 쿼리가 나가는 이유가 궁금합니다. Select 결과로 받아온 리스트의 size()를 실행시키는 게 count 쿼리를 다시 날리는 것보다 비용이 적을 것 같은데, count 쿼리가 다시 나가는 이유가 궁금합니다 :) 강의는 늘 즐겁게 듣고있습니다 감사합니다!
-
미해결스프링 MVC 2편 - 백엔드 웹 개발 활용 기술
검증 처리의 위치와 서비스 단계에서 validator처리 문제점
안녕하세요 김영한 은사님, 강의 열심히 잘 보고 있습니다.다름 아닌 개인 프로젝트 중 궁금한 질문이 생겨서 다음과 같이 남깁니다.Q1. 검증의 처리는 컨트롤러 or 서비스 단계 중 어디서 하는 것이 적당한가요? 구글링 결과 다 상황에 따라 다르다는 답변을 들었습니다. 그러나 실무 경험이 풍부한 김영한 강사님과 다른 수강생들의 의견이 궁금합니다. 만약 상황에 따라 다른 단계에 구현한다면 그에 따른 유지보수 문제는 감수하고 가는게 맞나요?Q2. 저는 재활용성을 우선시하여 서비스 단계에서 validator 를 주입하여 처리하고 있습니다. 그런데 binding result를 어떻게 처리해야할 지 모르겠습니다.물론 커스텀 에노테이션, bean validation을 사용하면 된다는 것을 알고 있습니다. 그러나 아직은 공부 단계이므로 validator을 통해서만 해결해보고 싶은데 방법이 있을까요? public String join(@ModelAttribute("member") MemberSaveForm memberForm,BindingResult bindingResult) { Member saveMember = new Member(memberForm); //아래와 같은 부적절한 코드 발생 bindingResult = memberService.join(saveMember, bindingResult); //서비스의 메소드 파라미터로 bindingResult를 넣고 그 메소드내에서 검증 처리 후 // 에러를 주입해서 다시 돌려주는 코드 if (bindingResult.hasErrors()) { return "/user/join"; } }
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
RestApi에 대하여
안녕하세요! 강사님 항상 좋은강의 정말 감사드립니다. 평소에 Api 특히 Rest APi에 대해서 너무 광범위한 사용과 문맥에 정말 개념이 잡기가 어려웠는데, 이번 강의를 통해서 많이 개념이 잡혀나가는것 같아 뿌듯하고 감사합니다. 공부를 하던중에 궁금한 것이 있는데 1. Rest api라고 하는건 mvc패턴에서의 api(템플릿 엔진을 주로 사용하여 리턴해주는 컨트롤러)는 Rest api의 범주에 들어오지 않는건가요? 2. 그리고 클래스 Annotation중에 @RestController가 붙으면 http body 부분에 json 형식으로 data가 디폴트로 나가는 건지 궁금합니다. 데이터를 text/plain이나, xml같은 형식으로 body에 response하려면 어떻게 해야할까? 라는 궁금증이 있습니다. 답변 부탁드립니다!
-
미해결스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
run실행시 테스트코드에서 컨트롤러로 돌리는 방법
실행시 이전강의에서 실행한 테스트코드만 실행되는데 다시 8080포트로 실행하는 방법을 모르겠습니다...