묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
updateItem질문입니다.
@PostMapping("/items/{id}/edit") public String updateItem(@PathVariable Long id, @ModelAttribute Item item) { Item findItem = itemService.findById(item.getId()); //더티 체킹 findItem.setId(item.getId()); findItem.setName(item.getName()); findItem.setPrice(item.getPrice()); findItem.setStockQuantity(item.getStockQuantity()); findItem.setAuthor(item.getAuthor()); findItem.setIsbn(item.getIsbn()); return "redirect:/items"; } 강의를 보지 않고 스스로 코드를 짜보고 있는데 이렇게 하니까 수정내역이 반영 되지 않더라구요 스스로 생각해봤을 때는 다음 2가지 이유 중 하나일 것 같은데 이유가 이유가 무엇인가요 ㅠㅠ? findItem은 영속성 컨텍스트가 관리하지 않는 객체가 된 것이다. 따라서 더티체킹이 되지 않는다. 영속성 컨텍스트가 관리하는 엔티티는 맞지만 Controller에는 트랜잭션이 없어서 반영이 안되는 것이다.
-
해결됨자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
도메인 주소 사용 질문
가비아에서 도메인 구입해서 사이트 접속을 할 때http://www.studying-developer.shop:8080/v1/index.html이런식으로 포트와 그 이하 경로도 써서 접속을 하셨는데, 보통 사이트 접속할때 포트를 입력하지 않고https://www.inflearn.com/과 같이 접속을 하는데이런식으로 접속할 수 있게 바꿀 수는 없을까요?
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
연관관계 매핑 관련 질문드립니다.
여기서 보시면 order_item 테이블이 orders 테이블과의 관계에서 fk를 가지는 연관관계의 주인이고엔티티상에서도 역방향으로 조회만 하기위해 List를 갖는것도 Order인데연관관계편의 메소드 addOrderItem()이 왜 Order엔티티에 들어가는지 이해가 되질않습니다.연관관계 주인 엔티티에 데이터를 넣어줄때 역방향으로도 영속성컨텍스트에 관리될 수 있도록주인엔티티에 만들어주는게 연관관계 편의 메소드라고 알고 있습니다.이부분에서는 연관관계의 주인이 1:N양방향으로 Order가 된건가요?? 답변 부탁드리겠습니다. 항상 좋은 강의 잘듣고 있습니다. 감사합니다 ❤️package jpabook.jpashop.domain; import lombok.Setter; import lombok.Getter; import javax.persistence.*; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @Entity @Table(name="orders") // 테이블 이름 매핑 @Getter @Setter public class Order { @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) // 양방향 매핑 - 다대일 (FK 가지고 있으므로 얘가 연관관계주인) @JoinColumn(name="member_id") // FK 매핑 private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) // orderItems 에 데이터를 저장하면 persist를 일일히 다할필요 없음, delete할때도 다같이 지워버림 private List<OrderItem> orderItems = new ArrayList<>(); /* persist(orderItemA) persist(orderItemB) persist(orderItemC) persist(order) -----케스케이드 적용-----=> persist(order) */ @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name="delivery_id") // 일대일이지만 fk가 있는곳에 연관관계주인을 잡는다. private Delivery delivery; private LocalDateTime orderDate; // 주문시간 @Enumerated(EnumType.STRING) private OrderStatus status; // 주문상태 [Order, Cancle] // 연관관계 편의 메소드 public void setMember(Member member){ this.member = member; member.getOrders().add(this); } public void addOrderItem(OrderItem orderItem){ orderItems.add(orderItem); orderItem.setOrder(this); } public void setDelivery(Delivery delivery){ this.delivery = delivery; delivery.setOrder(this); } }
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
랜덤 포트와 OAuth2 Redirect URI 설정 문제
랜덤 포트를 지정하는게 좋다고 설명해주셨는데요Kakao login OAuth2 를 사용해서 로그인하는 경우 Redirect URI를 지정해야합니다. Gateway 주소(http://localhsot:8080/user-service/api/...)를 등록해도 결국 localhost:54241 이렇게 넘어 가기 때문에 에러가 발생하는데 이 경우에도 랜덤 포트 사용하는게 맞나요?
-
미해결Practical Testing: 실용적인 테스트 가이드
테스트를 위한 메소드를 작성해도 괜찮은건가요?
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요!먼저 유사한 질문이 있었는지 검색해 보세요.서로 예의를 지키며 존중하는 문화를 만들어가요.안녕하세요 선생님. 강의 정말 재밌게 잘 듣고 있습니다. 이번 강의에서는 실제 비즈니스 로직으로 사용 될 createOrder() 로직을 작성하고 오로지 test 를 위한createOrder(LocalDateTime currentDateTime) 메소드를 추가로 작성하였는데 이처럼 오로지 테스트를 위한 메소드를 작성해도 괜찮은 것인지 궁금해서 질문을 남겨봅니다 ! 다른 개발자라면 처음 봤을 때, 같은 이름의 메소드가 두개라서 만약 해당 메소드를 호출하는 경우 직접 코드를 확인해봐야 하는 불편함이 있을 것 같은데 이런 경우 어떻게 해결하나요??
-
해결됨Practical Testing: 실용적인 테스트 가이드
만료되었는지 확인하는 메서드 검증
유익한 강의 만들어주셔서 감사합니다. 무분별하게 FakeRepository를 만들면서 실제 프로덕션 코드에서 작동하는것과 똑같이 내가 FakeRepository를 만들었을 거란 확신이 없이 테스트를 작성하던 와중에 이 강의를 보고 좀 깨우친 바가 많았습니다.해당 강의를 듣다가 이 케이스에서는 어떻게 검증하기 쉽도록 개선해볼 수 있을까 해서 질문드립니다.인증 코드라는 도메인 객체가 있습니다. 인증코드는 만료시간이라는 속성을 가지고 있고, isExpired()라는 메서드를 통해 해당 인증코드가 만료되었는지 확인할 수 있습니다.public boolean isExpired() { return LocalDateTime.now().isAfter(expirationTime); }강의를 듣기 전에는 이런 식으로 작성했습니다. 그런데 이런 식으로 작성하니 테스트 코드를 짜려고 하면 Fixture 설정 시 LocalDateTime.now()를 사용해서 만료일자를 설정해야 한다는 생각이 듭니다. 이런 경우에도 만료되었는지 검증할 수 있는 시간을 파라미터로 받도록 리팩토링해주는 것이 맞을지 궁금합니다!
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
jpa fetch join 페이지네이션에 대해서 질문이 있습니다.
안녕하세요. JPA N+1 문제를 공부하고 이를 해결하기 위해서 fetch join을 사용하고 있는데 fetch join의 단점으로 페이지네이션이 적용이 안되는 것으로 강의와 책을 보고 학습했습니다.이를 직접 실습하기 위해서 실습을 해보면 한 엔티티와 연관관계를 가지는 2개의 연관관계 엔티티를 fetch join한 결과 페이지네이션이 잘 적용되어서 혹시 제가 모르는 예외적인 상황이 있나 해서 질문 드립니다.아래는 코드이고, (피드와 책은 다대일 관계이고, 피드와 유저는 다대일 관계입니다)실제로 호출된 쿼리는 아래 사진과 같습니다.limit 처리가 잘 된것처럼 페이지네이션이 잘 적용이 됩니다. 제가 알기로는 분명 fetch join을 사용하면 페이지네이션이 적용이 안되어야 하는데 뭐가 문제인지 해서 질문 드립니다...!
-
해결됨Practical Testing: 실용적인 테스트 가이드
패키지 구조에 대한 질문
안녕하세요 강의에서는 패키지 구조를 api 아래에 api - service - productapi - controller - product 이렇게 구현하셨는데이렇게 구현하면 도메인이 많아지면 가독성이 떨어질 것 같아서 각 도메인마다 service, controller를 가지게 하는 구조는 어떻게 생각하시나요? api - product - service, controller가독성보다 더 중요한 장점이 있을까요?실무에서는 어떻게 하시는지 궁금합니다. 감사합니다~!
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
for(Member m : Members)에서 select 쿼리 발생하는 이유
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? 예2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예[질문 내용]안녕하세요. 양방향 연관관계와 연관관계 주인 1 - 기본 강의를 실습하다가 궁금한 내용이 생겨 질문드립니다.먼저, 아래와 같이 Member와 Team 객체 간의 양방향 연관 관계를 매핑하였습니다.DB에서 확인하기 위해 MemberA, MemberB를 같은 teamA에 소속되도록 저장한 후 Member findMember = entityManger.find(Member.class, memberA.getId()); 코드를 통해 DB에서 memberA를 가지고 왔습니다.위 코드를 실행시킨 결과는 아래 화면과 같습니다.제가 궁금한 내용은 아래 코드에서 select 쿼리가 왜 발생하는가? 입니다. 또 발생하는 select 쿼리의 해석이 어렵습니다.System.out.println("====for문에서 select 쿼리가 발생하는 이유가 뭘까?===="); for (Member m : members) { System.out.println("m name : " + m.getName()); } System.out.println("================");where 절에 해당하는 members0_.TEAM_ID=? 에 ? 값은 Member findMember = entityManger.find(Member.class, memberA.getId()); 코드를 통해 memberA가 가지고 있는 team_id 값을 가지고 있는 것일까요?또한, 그렇다면 어디서 team_id 를 가지고 있다가 비교를 하는 것인가요?마지막으로 결과값으로 MemberA, MemberB를 반환하는 것처럼 for문을 2번 반복하니깐 select 문도 2번 발생할 것으로 예상한 것과 달리 select문이 1번만 발생한 것도 이해가 가지 않습니다. 어떻게 select문 1번으로 memberA와 MemberB를 가지고 올 수 있나요? 궁금한 내용을 정리하면 아래와 같습니다.1. for(Member m : members)에서 select문이 발생하는 이유2. 해당 select문의 해석(특히 where절의 members0_.TEAM_ID=? 부분에 ? 값이 어떤 값인지, 어디서 team_id를 가지고 온 것인지)3. select문이 1번만 발생한 이유읽어주셔서 감사합니다. 답변 기다리고 있겠습니다!
-
해결됨Practical Testing: 실용적인 테스트 가이드
서비스 계층 통합테스트
안녕하세요강의 잘 보고 있습니다! 수업에서 서비스 계층을 테스트하실 때,@SpringBootTest를 이용해서 Repository 계층의 빈을 등록하고 주입받아서 사용하고 있습니다. 서비스 계층을 mock을 이용해 단위테스트로 하시지 않고 Repository 계층을 통합해서 사용하는게 많이 사용하는 방식인가요?실제 현업에서는 Service 계층을 어떻게 테스트 하는 지 궁금합니다. (단위테스트or 통합테스트)
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
em.find(), select문 질문
em.find(Member.class, 1L); System.out.println("========================"); tx.commit();위 코드를 수행한 결과 select문 이후에 '========================'가 출력되었습니다.em.find()를 하면 우선 1차 캐시에서 엔티티를 찾은 후, 없으면 바로 select문을 DB에 날리는 것이 맞을까요?tx.commit()하는 시점과 관계없이 1차 캐시에 엔티티가 없으면 바로 select 쿼리를 날리는 것이 맞을까요?
-
해결됨자바 ORM 표준 JPA 프로그래밍 - 기본편
스냅샷 업데이트 관련 질문
'dirty checking에서 스냅샷은 엔티티의 최신 상태를 반영하고 있다. 스냅샷은 계속 업데이트된다'가 맞을까요?스냅샷이 처음에는, 엔티티가 1차 캐시에 들어온 상태에 대한 스냅샷이지만,엔티티를 변경하면 스냅샷도 변경되는 것이 맞을까요? 예를 들어, member 테이블에 (1L, "A")가 저장되어 있고, 스냅샷도 (1L, "A")인 상황에서, 다음 코드를 실행하였습니다.Member findMember = em.persist(new Member(1L, "A")); findMember.setName("AA"); tx.commit();tx.commit()이 호출되면 flush()가 호출되고, 엔티티와 스냅샷을 비교하여 update 쿼리가 DB에 전달됩니다. 그리고 비교한 시점 이후 어디에선가 스냅샷이 변경되는 것이 맞을까요? 스냅샷이 변경된다고 생각하게 된 상황은 다음과 같습니다. (엔티티를 (1L, "AA")로 변경한 이후) 엔티티를 (1L, "A")로 변경을 했을 때, update 쿼리가 DB에 전달되었기 때문인데요, 만약, 처음에 스냅샷이 (1L, "AA")로 변경되지 않았다면, 엔티티와 스냅샷은 (1L, "A")로 동일하였을 것이고, 따라서 update 쿼리가 DB에 전달되지 않을 것이기 때문입니다.
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
쓰기 지연 관련 질문
상황: hibernate.jdbc.batch_size 옵션을 사용하지 않고, em.persist()를 4번 하였다.쓰기 지연 SQL 저장소에 insert 쿼리가 4개 존재하고, commit 시점에 DB에 insert 쿼리 4개가 전달된다는 것은 알겠습니다. 그런데, insert 쿼리가 DB에 전달될 때, 4번의 네트워크가 반복되는 것인가요? (https://www.inflearn.com/questions/41344/batch-size%EC%97%90-%EB%8C%80%ED%95%B4%EC%84%9C-%EC%A7%88%EB%AC%B8%EC%9D%B4-%EC%9E%88%EC%8A%B5%EB%8B%88%EB%8B%A4 이 질문을 보고 질문드립니다)그리고 4번의 네트워크가 반복된다는 것이 'DB와 커넥션 맺고 insert 쿼리 1개 전달하고 커넥션을 종료'하는 과정이 4번 반복된다는 뜻인가요? 그렇다면 em.persist()할 때마다 insert 쿼리를 보내는 것과 무슨 차이가 있는 것이죠...?
-
미해결자바 ORM 표준 JPA 프로그래밍 - 기본편
수업 자료 다시 다운로드
수업자료 한번 다운 받았었는데 컴퓨터 포맷해서 다 날라갔습니다.ㅜㅜ다시 다운 받을 수 없나요??
-
미해결실전! Querydsl
fetch().size()
fetchResult() 가 5.0 부터 권장하지 않는다 해서 fetch().size()를 사용한다고 하는데 List<MemberTeamDto> content = queryFactory .select(new QMemberTeamDto( member.id.as("memberId"), member.username, member.age, team.id.as("teamId"), team.name.as("teamName") )) .from(member) .leftJoin(member.team, team) .where( usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe()) ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .fetch(); int total = queryFactory .selectFrom(member) .leftJoin(member.team, team) .where( usernameEq(condition.getUsername()), teamNameEq(condition.getTeamName()), ageGoe(condition.getAgeGoe()), ageLoe(condition.getAgeLoe()) ).fetch().size(); int size = content.size(); return new PageImpl<>(content, pageable, total);아래처럼 count 쿼리를 날려서 구한 total 값과위에 content 쿼리문의 size()값이 다르게 나오던데이 size 값은 단지 PageRequet.of로 넣어준 size 값인가요?? 두 방식 중 total로 구하는 방식이 맞는건가요?
-
해결됨Practical Testing: 실용적인 테스트 가이드
단위테스트의 개념에 대해서 질문 드립니다!
안녕하세요! 테스트 강의가 드문데 정말 친절하게 잘 알려주셔서 감사하게 듣고 있습니다 :)아직 강의를 다 들은 것은 아니지만 강의 내용 중 궁금한 것이 있어 질문 드립니다.제가 테스트를 제대로 공부해본 적이 없어 혼자서 독학을 하며 공부했던 단위테스트는 주로 Mock과 항상 연관지어 설명이 되어 있었습니다. 통합테스트(@SpringBootTest)는 스프링 컨테이너를 띄우고 bean으로 등록된 모든 빈을 가지고 테스트를 하는 것인데 반해, 단위테스트는 해당 계층(Layer)을 테스트할 때 꼭 필요한 bean만 가지고 와서 최소 단위(메서드나 클래스)로 테스트를 진행한다고 저는 알고 있었습니다.그래서 예를 들어 Service 계층 테스트를 진행할 때면 Repository에 관련된 bean들은 Mockito 등을 사용해서 Mock을 만들고 InjectMocks를 해준다는 식으로 저는 공부를 하고 테스트 코드를 작성한 경험이 있습니다.그런데 오늘 강의에서 강사님이 설명해주시는 내용을 듣다보니 @SpringBootTest 와 같은 어노테이션과 상관없이 단위테스트를 진행하시는 것 같다는 인상을 받았습니다. Order에 대한 테스트를 진행하실 때도 단위테스트라는 언급을 하셨고, OrderSerivice에 대한 테스트를 진행하실 때도 @SpringBootTest를 사용하고 있지만 단위테스트를 하신다고 표현을 하시더라구요.혹시 통합테스트와 단위테스트를 구분하는 강사님만의 방법이 있는 것인지 궁금합니다! 장문 글 읽어주셔서 감사합니다!
-
미해결실전! 스프링 부트와 JPA 활용1 - 웹 애플리케이션 개발
p6spy, meta-inf 위치
현재 스프링 부트 3.0.6버전을 사용하고 있어서 p6spy를 사용하기 위해 pdf에 적힌 대로 파일을 추가하려고 했지만 META-INF 폴더를 찾을 수 없어서 질문 드립니다
-
미해결실전! 스프링 데이터 JPA
@Param의 존재 이유>?
@EntityGraph(attributePaths = "team") List<Member> findEntityGraphByUsername(@Param("username")String username);이번 강의를 복습하다 보니까 강사님께서 @Param을 사용하셨더라구요.(강의 20:59)findByAge(), findOptionalByUsername()과 같은 메소드는 @Param 애노테이션 없이도 잘 동작 했는데 따로 특별한 이유가 있는 것일까요?
-
미해결실전! Querydsl
fetchResult() deprecated
됐던데 앞으로는 강의의 searchPageComplex와 같은 방법 (content따로, total따로)으로만 구현하고 사용하면 되는 건가요 ?searchPageSimple 부분은 필요가 없는 건가요?
-
미해결자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
완성된 코드 자료를 그대로 실행했는데 오류가 발생합니다..
완성된 코드 그대로 서버를 실행했는데 이렇게 오류가 발생합니다.. 이유를 찾지 못해 질문드립니다