일대다 컬렉션 페치 조인 조회의 경우 팀A인 멤버가 1, 2, 3이면 DB는 멤버를 기준으로 조인을 해서 팀A인 row가 3개가 생기고 하이버네이트는 이를 받아와서 리스트로 반환(getResultList)해줄 때 리스트에 팀 A 엔티티를 3개 담아줍니다. 여기서 각각의 엔티티는 PK 값이 같기 때문에 서로 같은 엔티티를 참조합니다. (이렇게 이해를 했습니다!) 그러면 쿼리 횟수에 영향을 주는 건 페치 조인이고, distinct는 리스트에 중복 엔티티만 제거하는 역할만 하는 것 같은데 (select 다음 distinct가 추가되는 것 외에는 차이가 없음) 속도적인 면에서는 별 차이가 없는 것이 맞을까요??
안녕하세요. JPA를 공부하며 궁금한 점이 생겨서 질문드립니다. [상황] 현재 숙소 엔티티 내부의 이미지와 요금 정책등을 가져오는 로직을 개발 중입니다. 아래 2가지 방법을 고민중입니다. 1) @Query를 사용해 직접 DB에 쿼리문 전송(필터링 조건 포함) 2) roomId로 숙소를 가져와 객체들을 탐색하며 필터링 [고민] 위처럼 대용량의 데이터를 필터링해야 하는 경우에 @Query를 통해 데이터베이스에서 직접 필터링하는 경우와 자바 코드상에서 find해온 결과를 필터링해서 사용하는 것 중에 어느 것이 더 JPA스러운지, 어느 것이 더 성능상의 이점이 있는지 궁금합니다.
안녕하세요? 음악도 들으면서 게임도 하는 경우를 예시로 들으시면서 하나의 IP에 있는 애플리케이션들을 포트 번호로 구분한다고 하셨는데요 제가 스프링부트로 서버 애플리케이션을 개발해서 구동할 때는 8080 포트로 지정할 수도 있고 8081 포트로 지정할 수도 있고 리액트로 웹 사이트를 개발할 때도 3000번 포트로 지정할 수도 있고 4000번 포트로 지정할 수 있는데요 그냥 자바나 파이썬이나 C++로 프로그램을 짜도 이런 프로그램에도 포트번호가 있나요? (그리고 통신 기능이 없는 프로그램에도 포트 번호가 있나요?) 만약 있다면 다른 애플리케이션이 해당 애플리케이션의 포트 번호를 모르는데 어떻게 통신을 하나요? (포트번호를 명시적으로 지정한 적이 없는데 있다면)
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 아니오 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 안녕하세요. 스프링 핵심원리 고급편에서 다루는 주요 내용인 핵심기능과 공통(부가)기능을 어떻게 나눌 것인가를 듣다보니 어느덧 AOP 챕터까지 다다르게 되었습니다. 강의를 통해 부가기능의 종류에는 크게 로깅, 트랜잭션처리, 접근권한확인이 있다고 생각이 들었습니다. 이것들은 앞에서 다룬 개발 패턴이나 AOP를 사용하지 않고도 유틸리티성 클래스를 통해 처리가 가능한 것으로도 알고 있지만 SOLID 원칙, 유지보수 효율 증대, 중복 코드 제거 등의 많은 이점을 가져다주기 때문에 AOP와 같은 기술을 사용하는 것은 이해를 했습니다. 그러나 Filter/HandlerInterceptor를 사용해서도 부가기능을 처리할 수 있을 것으로도 생각이 드는데요.(스프링 MVC 강의 학습을 통해 느낀 점입니다.) 저와 비슷한 생각을 가지고 계신 다른 분께서 질문한 글의 답변을 인용하자면 웹과 관련된 공통(부가)기능(특정 메뉴 접근권한 확인, 로그인 여부 확인 등)는 Filter/HandlerInterceptor를 통해 처리하고, 순수한 자바 코드를 통한 공통 (부가) 기능은 AOP를 이용하는 것이 맞는 것인지 궁금합니다. (참고 질문: https://www.inflearn.com/questions/495293 ) 물론 더 나아가 시큐리티를 알고 있다면 이런 질문 내용도 다른 방식으로 해결이 가능하겠지만, 만약, 시큐리티를 현재 모르고 있다라는 가정하에 위와 같이 실무에서도 처리하는게 맞는지 첨언 부탁드리겠습니다. 미리 답변 감사드립니다.
안녕하세요. API URI 설계에 대해서 궁금한점이 있습니다. 멤버 도메인과 주문 도메인이 있을 때 (JPA강의 예) 만약 해당 멤버의 주문을 검색하고자 하여 요청을 할 때 API URI는 어떻게 해야할까요? 1번. GET /members/{id}/orders 2번. GET /orders 이 둘중에서 어떤 URI로 설계해야 할지 궁금합니다. 인터넷 서칭 결과 관련있는 리소스는 1번처럼 사용한다고 나오는데 jwt를 사용할 경우 2번이 더 적합한게 아닌가라는 생각이 듭니다. 어떤 기준을 적용하여 1번과 2번 중 어떤 API URI 설계를 사용해야할 까요?
재귀적 락을 허용 하지 않았을때 ReaderWriterLock은 Write할때 Read가 같이 일어나면 Write하기 전에 있던 데이터와, Write한 후의 데이터가 공존해서 Read해가기 때문에, ReaderWriterLock을 사용 하는거 같은데(Read만 해갈때는 문제 없어서 Read는 공용으로 가능) 어떤 경우에 재귀적 락을 허용하는지 잘 모르겠습니다. 재귀적 락을 허용했을때는 한 쓰레드가 여러개의 데이터를 write,read할때 사용 되는건가요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. public class SecurityConfig extends WebSecurityConfigurerAdapter 에서 WebSecurityConfigurerAdapter 이게 지원중단이라떠서 더이상 진행이 불가능한데 어떻게 해결할 수 있나요?
코틀린에서는 null 사용을 안전하게 하기 위해서 null 이 들어갈 수 있는 변수를 완전히 다른 타입으로 간주하고 아래와 같이 효과적으로 관리할 수 있다. 라고 말씀해주셨는데요 그렇다면 String과 String? 타입은 엄연히 다른 타입 인것이고 String? 이 자체를 하나의 타입으로 간주해야하는건가요? String? 이렇게 생긴 타입은 코틀린에서는 클래스로 정의 되어 있지 않아서요..!
제가 혼자 만들어보면서 느꼈던 점은, "session에서 lock을 걸지 않고 recvbuffer의 writesegment를 가져오거나 DataSegment를 읽어올 때 lock을 걸면 최소한의 범위로 할 수 있을 것 같다" 입니다. 강사님께선 Session의 Send, RegisterRecv, OnRecvCompleted에 하나의 _lock 오브젝트로 전부 잠구셨는데 이렇게 되면 예를 들어 OnRecvCompleted를 호출해서 _lock 범위 내에서 처리하는 동안 Send를 호출하면 Send는 OcRecvCompleted가 끝날 때 까지 대기해야하는 상황이 발생하지않나라는 걱정이 조금 됩니다.
@PostMapping("/members/new") public String create(MemberForm form) { Member member = new Member(); member.setName(form.getName()); memberService.join(member); return "redirect:/"; } 에서 MemberForm.java를만들면 form에서 입력된 name이 memberForm으로들어간다고하더라고요 근데 어떻게 form에서 입력된값이 바로 MemberForm.java로 들어갌수있는지 이해가 안가는데 원래 파라미터 받아서 setName해서 memberform안에 name를 저장해야되는거 아닌가요? 단순히 form에서 값입력후 전송했는데 MemberForm 으로 넘어가는걸 모르겠습니다. 그러니 위에 바로 form.getName()이렇게 바로 불러올수있는게 이해가 안가는데 어떻게 가능한걸까요
강의 내용중, Order 도메인을 작성할때 다음 스크린샷처럼 Member, Delivery 엔티티를 사용하여 this 키워드를 사용할때 Cannot access jpabook.jpashop.domain.Member 에러가 나고 있습니다. Member와 Delivery, Order 는 모두 예시로 올려주신 코드와 확인하여 똑같이 작성한걸 확인했지만 혹시 몰라 제가 작성한 코드를 같이 올리겠습니다. package jpabook.jpashop.domain; import lombok.Getter; import lombok.Setter; import javax.persistence.*; import java.util.ArrayList; import java.util.List; @Entity @Getter @Setter public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String name; @Embedded private Address address; @OneToMany(mappedBy = "member") private List<Order> orders = new ArrayList<>(); } package jpabook.jpashop.domain; import lombok.Getter; import lombok.Setter; import javax.persistence.*; @Entity @Getter @Setter public class Delivery { @Id @GeneratedValue @Column(name = "delivery_id") private Long id; @OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY) private Order order; @Embedded private Address address; @Enumerated(EnumType.STRING) private DeliveryStatus deliveryStatus; } package jpabook.jpashop.domain; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import javax.persistence.*; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; import static javax.persistence.FetchType.*; @Entity @Table(name="orders") @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) // 이거는 한 도메인 안에서 생성 메서드 등을 통해 로직을 구현했을 경우에 // 접근을 막기위해 사용한다 // 누구는 여기 만들어진 createOrder 를 통해서 주문을 생성하고 // 누구는 Order order = new Order -> order.setOrder로 생성하고 하면 나중에 골치아파치므로 // 애초에 public 으로 지정되어 있지 않은거 + 롬복통한 getter setter 를 통한 코딩을 막아준다 public class Order { @Id @GeneratedValue @Column(name = "order_id") private Long id; @ManyToOne (fetch = LAZY) @JoinColumn(name="member_id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) // cascade all 걸어주면 private List<OrderItem> orderItems = new ArrayList<>(); // persist(orderItemA) // persist(orderItemB) // persist(orderItemC) // persist(order) 를 cascase all 안걸어주면 이렇게 넣어야하는데 // 걸어주면 persist(order)하면 자동적으로 다 넣어줌 딜리트도 마찬가지로 다 같이 지워줌 // 즉, 원래는 order 에 들어가는 delivery 나 orderItems 등은 다른 테이블에 같이 걸려있잖아 그걸 // 일일히 다 테이블마다 찾아가서 넣어줘야하는데 cascade all 걸어주면 알아서 그걸 다 연동해서 cd 해줌 @OneToOne (fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name="delivery_id") private Delivery delivery; private LocalDateTime orderDate; @Enumerated(EnumType.STRING) private OrderStatus status; // 주문상태 order cancel //연관관계 편의 메서드 = 양방향일때 쓰면 편한 메소드 //이게 뭐냐면 연관관계 맺어줬으면 DB딴에서는 이런거 안해줘도 다 알아서 동작하긴 하는데 // 비지니스 로직상에서는 이렇게 set할수 있는 연관관계 메서드가 있어야 구현할때 편함 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); } //연관관계 메서드 위치는 컨트롤하는쪽에 위치하는게 좋음 비지니스 로직에 의하면 // public static void main (String[] args){ // Member m = new Member(); // Order o = new Order(); // // m.getOrders().add(o); --> 이거 할필요가 없어짐 // o.setMember(m); // } // 원래는 연관관계 메서드가 없으면 이렇게 일일히 비지니스 로직딴에서 데이터 객체 생성후 member 에도 넣어주고 order 에도 넣어주고 해야하는데 // 연관관계 메서드를 만들어 놓으면 로직딴에서 저짓할필요가 없이 편해짐 // ... 은 가변파라미터, String 이라 치면 몇개를 넣어도 다 카바 가능 -> list = 가변파라미터 하면 다 리스트에 들어감 차곡차곡 //생성메서드 public static Order createOrder(Member member, Delivery delivery, OrderItem... orderItems){ Order order = new Order(); order.setMember(member); order.setDelivery(delivery); for (OrderItem orderItem:orderItems) { order.addOrderItem(orderItem); } order.setStatus(OrderStatus.ORDER); order.setOrderDate(LocalDateTime.now()); return order; } //비지니스 로직 //주문취소 public void cancel(){ if(delivery.getDeliveryStatus()==DeliveryStatus.COMP){ throw new IllegalStateException("배송 완료된 상품은 취소불가"); } this.setStatus(OrderStatus.CANCEL); for(OrderItem orderItem:orderItems){ orderItem.cancel(); } } //전체주문가격 조회 public int getTotalPrice(){ int totalprice = 0; for(OrderItem orderItem:orderitems){ totalprice += orderItem.getTotalPrice(); } return totalprice; } } import 구문을 직접 작성하여 엔티티들을 직접 임포트까지 해보고, 로직상에서 아예 jpabook.jpashop.~~ 처럼 직접 임포트 구문을 작성해서 시도도 해보았지만 해결이 되지 않아 질문을 올리게 되었습니다. 확인부탁드립니다.