안녕하세요. Entity 선언 시 data class vs class 질문드리려고 합니다. 아래 질문은 data class를 기반으로 했지만 사실 궁금증 시작은 "class가 엔티티에 더 맞지 않나?" 라는 생각에 질문드립니다. 질문 1. data class 선언시 프록시 질문 제가 알기로 ManyToOne lazy loading할 때 프록시 기능을 사용한다고 알고 있습니다. data class가 자바 record와 마찬가지 final인 것으로 아는데 그렇다면 지연 로딩이 정상적으로 동작하지 않다고 생각됩니다. 혹시 여기서는 지연 로딩을 사용하지 않아서 data class를 사용하신 것인지 궁금합니다. 질문 2. data class 사용이 맞다면 equals & hashCode 질문 결궁 두 값 동일성을 비교할 때 id를 기반으로 하는 것이 성능에 좋을 것 같다고 생각됩니다. 혹시 실무에서 data class 나 class 사용하실 때 id기반으로 equals와 hashCode를 오버라이딩 하지 않고 전체 필드로 하시는지 궁금합니다. 질문 3. data class 목적 제가 알기로는 data class는 response와 같이 불변 데이터에 많이 쓰이는걸로 알고 있습니다. 그래서 copy와 같은 메서드를 제공하는 것으로 알고 있습니다. data class를 사용할 때 물론 copy를 사용하시진 않겠지만 영속성 컨텍스트 같은 기능을 쓰려면 직접 변경해야 합니다. 불변 클래스 목적과 jpa entity와 잘 맞지 않는 것 같아서 질문드립니다. 질문 4. equlas 질문 만약 양방향 참조가 있는 entity라면 무한 루프에 빠질 가능성이 없는지 궁금합니다. 이와 같은 이유로 2번을 질문 드렸는데 질문 2번에서 내용이 빠진 것 같아서 따로 한 번 더 질문 드립니다. 제가 실무에서 써보지 않았고 코틀린 관련해서는 경험이 부족해서 잘못된 질문이 있다면 알려주시면 다시 질문 남기겠습니다. 좋은 강의 감사합니다. 감사합니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 여기에 질문 내용을 남겨주세요. t1 t2 가 동시에 실행되지 않고, 약간의 시간차가 있는 상태에서 두 스레드가 CPU 캐시를 통해 balance를 읽어들이고 쓰면 잔액이 200원이 될 수 있을까요?
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문 전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 만약 무한정 대기할 수도 있는 상황에서 t1.join(50); t2.join(50); main의 코드를 이렇게 바꿔봤는데 결과가 똑같더라구요 이게 왜 그런지 알고 싶습니다.
찾아보니 아래처럼 나옵니다. ``` fetchResults() 는 Querydsl 5.x부터 deprecated(더 이상 권장되지 않음) 처리되었습니다. fetchResults() 는 count 쿼리 와 content 쿼리 를 내부적으로 두 번 실행 해서 결과를 가져옵니다. 즉, 전체 개수( total count )와 페이징된 결과( results )를 한 번에 반환하려고 했는데, JPA 환경에서는 count 쿼리 최적화 문제 SQL이 복잡해질 경우 성능 저하 문제 Querydsl 5.x 이후로는 직접 count 쿼리와 content 쿼리를 분리 해서 호출하는 방식을 권장합니다. ```
========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요. 기본형 특화 스트림 을 공부 하다가 갑자기 float가 생각나서 질문을 드립니다. 저가 코드를 쳐보니 스트림을 이용해서 스트림<Float>을 만들 수 있다는 것을 확인하였습니다. 현재 개발에서 float 및 스트림<Float>을 사용할까 입니다. double형도 있지만 float도 있어서 사용 할수 도 있겠다 싶어서요. 그래서 질문은 현시점에서 스트림<Float>및 Float 를 만들어서 어느 정도 사용하는지 알고 싶습니다. 답변 부탁 드립니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 영한님 안녕하세요. Spring Data JPA가 제공하는 save, saveAndFlush 메서드에 대해 궁금한 점이 있는데요. 흔히들 saveAndFlush는 save와 달리 트랜잭션 커밋시점이 아닌, 영속성 컨텍스트 변경 사항을 즉각 DB에 반영하여, DB 통신이 증가한다는 단점이 있다고 합니다. for (int i = 0; i < 3; i++) { repository.save(entity); } 그런데, 제가 의문이 드는 점은 save 메서드도 위와 같은 상황이 있을 때, 커밋 시점에 DB에 flush를 하기는 하지만, batch insert가 아니기 때문에 DB 통신 자체는 단 건으로 총 3번 일어나는 것 아닌가요? 따라서, DB 통신 자체에서 saveAndFlush가 얻는 이점은 없다고 생각되는 데 어떤 이점이 있을까요? 감사합니다
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 임베디드 타입 강의 (5:30)에서, @ManyToOne을 지웠는데, 강사님의 Team의 @OneToMany가 어떻게 되어 있기에 H2 데이터베이스와 연결했을 때, Member table에 FK로 TEAM_ID가 들어가게 되는지 (6:58)궁금합니다. 저 같은 경우에는, Team의 어노테이션이 이렇게 되어있는데, @OneToMany(mappedBy = "team") private List<Member> members = new ArrayList<>(); 그대로 실행시켰을 때, 아래처럼 매핑이 잘못되었다는 문구가 뜹니다. Exception in thread "main" org.hibernate.AnnotationException: Collection 'hellojpa.Team.members' is 'mappedBy' a property named 'team' which does not exist in the target entity 'hellojpa.Member'
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] fetch join의 동작에 대하여 의구심이 들어 찾아봤더니 "fetch join의 경우 SQL에서 사용하는 join의 종류가 아닌 JPQL에서 성능 최적화를 위해 제공하는 기능인데요. fetch join은 조회하는 주체가 되는 entity 외에 fetch join이 걸린 연관 관계가 있는 entity까지 함께 select 하여 영속화합니다." 라고 합니다. 영속성 컨텍스트는 기본적으로 트랜잭션 범위내에서 생성되고 종료되는거 할거같은데, 어떻게 컨트롤러에서 트랜잭션이 걸려있지 않은 메서드를 바로 호출해서 사용해도 이러한 것이 가능한지 궁금해서 찾아보니 OSIV라는게 있더군요. OSIV는 기본적으로 트랜잭션이 시작 후 종료되어도 일정 부분은 영속성 컨텍스트를 웹요청 전체에 열어둔다. 때문에 OSIV를 끄면 지연로딩같은건 컨트롤러에서 이루어지게 코딩해두었으니 예외가 뜬다. 근데 여기서 문제는 OSIV를 끄면 fetch join도 작동안해야할거같은데 작동을 합니다. 레포에 눈에 보이지 않는 트랜잭션이라도 걸려있는건가요?
[질문 내용] OrderItem에서 가격 총합을 구할 때 자기 자신의 필드임에도 return orderPrice * count; 이렇게 바로 쓰기 보다는 public int getTotalPrice() { return getOrderPrice() * getCount(); } get으로 가져오시더라구요. 그렇다면 Order에서는 //==조회 로직== public int getTotalPrice() { int totalPrice = 0; for (OrderItem orderItem : orderItems) { totalPrice += orderItem.getTotalPrice(); } return totalPrice; } for문에 orderItems에도 getOrderItems()로 하셨었나? 하고 봤더니 이거는 바로 접근을 하시는데 자기 필드를 get으로 접근 하는 것이 조금 어색한데, 혹시 이유가 있을까요?
안녕하세요! 토비님. 헷갈리는 개념이 하나 있어서 여쭤보고 싶습니다. 바로 헥사고날 아키텍처에서 UseCase의 책임 범위인데요. 우선 정답은 없다는 것은 알고 있습니다. 다만 Best Practice나 권장되는 방법이 있는지, 그리고 토비님의 고견이 궁금하여 질문드리게 되었습니다. 기능 단위로 UseCase 인터페이스 분리하기 vs 연관된 기능은 UseCase 인터페이스에 묶음으로 제공하기(메서드별로) 입니다. 전자는 SRP가 매우 엄격하게 준수되고, 테스트 용이성, 개별 인터페이스별로 정책을 다르게 적용할 수 있다는 장점들이 있지만 과도하게 인터페이스화를 하다 보니 관리할 포인트가 많아져 복잡해진다는 게 단점인 것 같습니다. 후자는 SRP가 엄격하게 준수되지 않더라도, 관련된 기능을 응집도 있게 관리하기 때문에 테스트 용이성이 조금 떨어지고, 일관된 정책을 관리하거나 인터페이스가 비대해질 수도 있다는 단점이 있지만, 응집도 있게 관리하여 유지보수에는 편한 장점이 있는 것 같습니다. 코드를 예시로 보면 아래처럼 콘서트를 조회한다고 했을 때, 일반적으로 PK를 기반으로 조회하지만, 아래와 같이 콘서트명도 unique하고, 가수도 1개의 진행 중인 콘서트만 가지고 있을 수 있을 때 조회 조건이 Id, Name, ArtistName으로 분류될 수 있다고 예시를 들어보겠습니다. public interface GetConcertUseCase { ConcertResult findById(Long concertId); ConcertResult findByName(String name); ConcertResult findByArtistName(String ArtistName); ConcertResult findByIdWithSchedules(Long concertId); // Aggregate Member인 ConcertSchedule 목록 정보도 포함하여 조회 } 위에처럼 구성하는 게 후자 방식이고 응집도가 높다고 생각합니다. 그런데 해당 방식은 유스케이스가 비대해질 수 있고, 단일 책임 원칙에서 벗어날 수 있다는 의견 때문에 조회 목적별로 유스케이스 분리하는 것을 권장하는 의견도 있습니다. (전자 방식) public class GetConcertByIdUseCase { ... } public class GetConcertByNameUseCase { ... } public class GetConcertByArtistUseCase { ... } public class GetConcertByIdWithSchedulesUseCase { ... } 정답은 없어서 프로젝트 규모나, 각자의 스타일, 기능 분석에 의해 정해지겠다만, 보편적으로 이런 경우 어떻게 접근하는 게 Best Practice인지 감이 잡히질 않아 질문드리게 되었습니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? 예 [질문 내용] 본래 DB에 쿼리를 날리는 행위는 트랜잭션 안에서 이루어져야하는데 본 강의부터 뒤쪽 강의까지 컨트롤러단에서 직접 레포지토리 메서드를 호출하여 코드를 작성하는걸 볼 수 있습니다. 제가 알아본 바로는 아래와 같다고 합니다. 쓰기 작업 : 반드시 트랜잭션 필요. 조회 작업 : 트랜잭션 없어도 가능. 단, 지연 로딩 시 트랜잭션 없으면 예외 발생. 실무 규칙 : Repository는 트랜잭션 안 열고, Service 계층에 @Transactional로 비즈니스 단위 트랜잭션 관리. 읽기 전용 조회 최적화 : @Transactional(readOnly = true) 사용 → 성능 최적화 + 예외 방지. 근데 뒤쪽 강의에서는 fetch join을 사용하니 지연 로딩에 대한 예외가 발생안한다고 쳐도 현재 이 강의 초반에 /api/v1/simple-orders 에 대한 메서드에서는 실제로 지연 로딩에 의한 쿼리를 호출합니다. 그렇다면 결국 트랜잭션이 없는 상태에서 이루어진 것이니 LazyInitializationException 예외가 발생해야하는거 아닌가요? 그리고 보통 실무에서 컨트롤러에서 fetch join 쿼리 메서드(트랜잭션이 걸려있지 않은) 등을 레포지토리에서 바로 호출하는 경우가 흔한가요?
공부중인데 내용이 너무 좋아서 블로그에 공부한 예제 코드와 정리된 내용을 일부 작성하려 하는데 괜찮을까요?? 스크린샷으로 첨부하거나 그런건 아니고 코드는 제 ide 에서 실행한것과 git repo 에 올리면서 공유하려고 해~ 그리고 공부한 내용들은 직접 작성 하고 정리해서 올리려고 하는데 괜찮은지 궁금해서 질문해!!
1. 현재 학습 진도 4-5 수강중 트랜잭션 내 isolation level에 따른 데이터 consistency 보장을 위해, WAL(Write-Ahead Logging)시 내부적으로 사용하는 UNDO LOG와 REDO LOG를 활용한다. 2. 어려움을 겪는 부분 그러면 트랜잭션 내에서 rollback을 수행하면, UNDO LOG를 기반으로 디스크 내용을 트랜잭션 수행 이전 상태로 되돌린다고 이해했습니다. 맞게 이해한걸까요? 만약 이게 맞다면, WAL로 인해 트랜잭션 내 작업들은 커밋되기 전에 디스크에 반영되지 않으므로, rollback된다면 UNDO LOG를 활용하지 않더라도 디스크 내 데이터가 이전 내용임이 보장되지 않나요? 롤백 시 UNDO LOG가 어떤 부분에서 활용되어야 하는지 이해하지 못했습니다.