학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] 안녕하세요 HQL과 JPQL의 관계를 정확히 알고 싶습니다. https://docs.jboss.org/hibernate/orm/4.3/devguide/en-US/html/ch11.html The Hibernate Query Language (HQL) and Java Persistence Query Language (JPQL) are both object model focused query languages similar in nature to SQL. JPQL is a heavily-inspired-by subset of HQL. A JPQL query is always a valid HQL query, the reverse is not true however. Both HQL and JPQL are non-type-safe ways to perform query operations. 라고 되어있는데, 그럼 hibernate 구현체에서 JPQL을 작성하게 되면 hibernate에서 내부적으로 이를 해석한 후 HQL로 변환해서 처리하는 것인가요? OKKY - JPQL 에서 limit 절이 왜 저는 될까요?? JPQL에서 limit절 지원 안된다는 내용을 접했었는데 해당 글에서 처럼 limit을 추가하니 작동을 잘됐습니다. 그래서 찾아보니 HQL이 이를 지원한다라고 되어있는데.. JPQL에선 지원이 안되는데 HQL에서는 지원이 된다라는 내용이 좀 이해가 잘 안가서 둘의 관계에 의문을 갖게 되었습니다 감사합니다
안녕하세요! 다름 아니라 [ Hello JPA - 애플리케이션 개발 강의 ]를 따라가면서 하고 있는데, 강의와 다르게 나옵니다ㅠㅠ 이런 식으로 id 1L인 member를 먼저 등록한 다음, 드래그 한 부분의 id를 2L로 바꿔주고 다시 서버를 띄우면 강사님께서는 서버를 다시 띄워도 이렇게 1L과 2L이 나오는데 저는 서버를 다시 띄우면 2L만 나옵니다. rollback을 안 했는데도 id 2만 등록되어있습니다. 그리고 이렇게 했을 때 강사님께서는 위에 아이디 1과 2의 member가 등록되어있는 상태에서 돌리셨기 때문에 System.out.println("findMember.id = " + findMember.getId()); System.out.println("findMember.name = " + findMember.getName()); 이 부분이 잘 출력되는데 저는 rollback이 되어 출력이 안 됩니다.. 무슨 차이일까요? 강사님께서 제공해주신 <최신 프로젝트 설정하기>로 다운로드 받아 진행하였습니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. spring-io에서 만들어서 intellj에서 실행했는데 실행이 되지가 않습니다 뭐가 문제일까요 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요.
안녕하세요, 질문이 있어서 글 남기게 되었습니다. 이런식으로 지점(branch)명에 맞는 공간(space)중 미팅룸 리스트를 보여주고 해당 미팅룸의 해당 날짜의 예약들도 보여주는 기능을 구현하고자 @Override public List<Reservation> findReservationListByDateAndBranchName(LocalDateTime startDatetime, LocalDateTime endDateTime, String branchName) { return queryFactory .select(reservation) .from(reservation) .join(reservation.space, space).fetchJoin() .join(space.branch, branch) .where(branch.branchName.eq(branchName), reservation.reservationStartDateTime.between(startDatetime, endDateTime), space.dtype.eq("MeetingRoom") ) .fetch(); } 이런 코드를 작성하였는데 아래와 같은 연관관계 때문에 Reservation Entity @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "reservation") public class Reservation extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "reservation_id") private Long reservationId; @Column(name = "reservation_start_date_time") private LocalDateTime reservationStartDateTime; @Column(name = "reservation_end_date_time") private LocalDateTime reservationEndDateTime; @OneToMany(mappedBy = "reservation") private List<MemberReservation> memberReservations = new ArrayList<>(); @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "space_id") private Space space; } Space Entity @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Inheritance(strategy = InheritanceType.JOINED) @Table(name = "space") @DiscriminatorColumn public abstract class Space { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "space_id") private Long spaceId; @NotNull @Column(name = "space_name") private String spaceName; @NotNull @Column(name = "space_floor") private int spaceFloor; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "branch_id") private Branch branch; @OneToMany(mappedBy = "space") private List<Reservation> reservations = new ArrayList<>(); @NotNull @Column(name = "dtype", insertable = false, updatable = false) private String dtype; } Space를 상속받는 FocusDesk, MeetingRoom, RechargingRoom @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "focus_desk") public class FocusDesk extends Space { //추후에 해당 엔티티에 맞는 필드들 추가 } @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "meeting_room") public class MeetingRoom extends Space { @Column(name = "meeting_room_capacity") @Positive private int meetingRoomCapacity; } @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "recharging_room") public class RechargingRoom extends Space { //추후에 해당 엔티티에 맞는 필드들 추가 } select r1_0.reservation_id, r1_0.created_date, r1_0.last_modified_date, r1_0.reservation_end_date_time, r1_0.reservation_start_date_time, s1_0.space_id, s1_0.dtype, s1_0.branch_id, s1_0.space_floor, s1_0.space_name, s1_2.meeting_room_capacity from reservation r1_0 join (space s1_0 left join focus_desk s1_1 on s1_0.space_id=s1_1.space_id left join meeting_room s1_2 on s1_0.space_id=s1_2.space_id left join recharging_room s1_3 on s1_0.space_id=s1_3.space_id) on s1_0.space_id=r1_0.space_id join branch b1_0 on b1_0.branch_id=s1_0.branch_id where b1_0.branch_name=? and r1_0.reservation_start_date_time between ? and ? and s1_0.dtype=? 이런 쿼리가 나가게 됩니다. 처음에는 dtype 없이 MeetingRoom 만 join 하고 싶었지만 reservation.meetingRoom 이불가능하여(reservation은 space랑 매핑 되어있으니까) 불가능하여 이방법 밖에는 떠오르지 않았습니다. 문제는 위의 쿼리처럼 쓸모없는 테이블들을 강제로 조인한 후에 다시 where절의 dtype으로 구분을 해야한다는 것입니다. @Query("SELECT new com.example.sabujak.reservation.dto.ReservationQueryDto(r.reservationStartDateTime, r.reservationEndDateTime, s.spaceId, s.spaceFloor, s.spaceName, m.meetingRoomCapacity) " + "FROM Reservation r " + "JOIN r.space s " + "JOIN MeetingRoom m ON m.spaceId = s.spaceId " + "JOIN s.branch b " + "WHERE b.branchName = :branchName " + "AND r.reservationStartDateTime BETWEEN :startDateTime AND :endDateTime") 이런식의 jpql로는 해결이 가능하지만 추후에 정렬조건을 동적으로 받아야 하기에 querydsl을 사용해서 최대한 좋은 방향으로 사용하고 싶은데 어떻게 해야할지 잘 모르겠습니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 안녕하세요. 섹션6 날짜와 시간 문제풀이2번째에서 막혀서 질문을 드립니다. 현재 저의 코드 상태가 그림으로 보시는 봐와 같이 이런 상태이고, 지금 이 상태 에서, 월요일이 첫 시작 일 때(2024년 1월 1일기준), 월요일에서 날짜를 넣는 방법을 모르겠더라고요. 이럴 때 에는 문제와 풀이2 해석을 보는게 나은지? 아니면 검색을 해서 라도 푸는게 나은지 알고 싶습니다. 답변 부탁 드립니다. 참조한 클래스는 TestLoopPlus, TestAdjusters 이 두개를 참조 했습니다.(클래스 이름 +import는 pdf에서 봄)
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] LinkedHashSet은 HashSet과 같은데 Node를 추가해서 입력 순서를 유지한다 들었습니다.그럼 만약에 HashIndex가 같은 경우(해시 충돌) Node도 HashSet과 같이 List 형식으로 저장이 되는게 맞을까요?
안녕하세요, 강의를 듣다가 몇가지 질문이 생겼습니다. 1. Pessimitic Lock와 Optimitic Lock 는 select 구문(@Query("select ...) 나 find 쿼리메서드)에서만 @Lock을 적용하는거라고 이해하면 될까요? 2. Pessimitic Lock 과 Optimitic Lock 의 벌크 수정 쿼리는 어떻게 처리가 되는건가요? 2-1. Pessimitic Lock 은 select 절로 데이터를 가져오지 않는다면 어떻게 벌크 수정이 되는건가요? 2-2. Optimitic Lock 은 벌크 연산에서 직접 버전을 수정하는게 맞을까요? 좋은 강의 감사합니다.
SQL의 ON절과 QueryDsl의 ON절 간에 차이가 있어보여 질문드립니다. SQL의 ON절에서는 테이블과 테이블 간에 어떤 컬럼을 기준으로 조인될 것인가를 명시하는 기능을 하는데 비해, QueryDsl에서는 join메서드가 그 기능을 포함하고 on메서드가 마치 sql의 where절의 역할을 하는 것(그렇기 때문에 QueryDsl에서는 SQL과 달리 on 메서드와 where 메서드를 함께 사용할 수 없음)으로 보이는데 맞을까요?
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? ( 예 /아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? ( 예 /아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? ( 예 /아니오) [질문 내용] @Repository public class MemberRepository { @PersistenceContext private EntityManager em; .... } 위 코드에서 질문이 하나 있는데요, EntityManagerFactory가 스프링 빈으로 디폴트로 등록이 되고 위 em에다가 entitymanager를 만들어서 주입을 해 주는 것인지, 아니면 EntityManager가 스프링 빈으로 아예 등록이 되고 저 위에다가 주입이 되는 것인지(아닐 것 같기는 합니다!)궁금합니다
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 네 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 네 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 네 [질문 내용] 1. 회원 서비스를 테스트할 때, DI를 하는 이유를 저는 아래처럼 이해했는데 이것이 맞는 이해인지 궁금합니다. MemberService() 를 실행하는 순간 MemoryMemberRepository 가 new로 생성되고, 그 다음줄에서 MemoryMemberRepository 를 새롭개 new로 생성한다. 현재의 코드에서는 Store 가 static 하게 선언되었으므로 그런 문제가 발생하지 않겠지만, 그렇지 않다면 MemberService 와 MemoryMemberRepository 가 서로 다른 레포지토리 인스턴스를 가지게된다. 위 내용이 맞다면, 모듈 테스트를 하지 않는다는 가정하에 해당 부분 뒤에 나오는 스프링 통합 테스트를 할 때는 이미 스프링 컨테이너에 레포지토리가 등록되어 있으므로 생성자를 활용한 의존성 주입이 필요없는 것이 맞나요? 아래 그림은 최종적으로 제가 구조를 이해한 것을 구조화 한 것인데 혹시 틀린 부분이 있는지 궁금합니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] 더 큰 숫자 찾기문제에 int max = (a > b) ? a : b;가 아닌 String status = (a > b) ? "10" : "20";는 틀린 답인가요? 이유도 궁금합니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 익명 클래스는 이름이 없는 지역 클래스라고 하셨는데 익명 클래스를 메소드 파라미터로 넘기는 부분에서 사용하기 때문에 지역 클래스라고 하는건가요??
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예 [질문 내용] 여기에 질문 내용을 남겨주세요. 사진에서 4. flush, 5. commit은 무엇을 의미하는 것인지 궁금합니다.
안녕하세요 강의 잘 듣고 있습니다. 다름이 아니라 프로젝트를 업그레이드 하는 과정에서 오류가 생겨 질문 드립니다. package ShopProject.myShopProject.Domain; import ShopProject.myShopProject.Domain.Item.Item; import ShopProject.myShopProject.Domain.Order.Order; import jakarta.persistence.*; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; import lombok.Data; import lombok.Getter; import lombok.Setter; 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",cascade = CascadeType.REMOVE) private List<Order> orders = new ArrayList<>(); private String loginId; private String password; @OneToMany(mappedBy = "member") private List<LikedItem> likedItems = new ArrayList<>(); } package ShopProject.myShopProject.Domain; import ShopProject.myShopProject.Domain.Item.Item; import jakarta.persistence.*; import lombok.Getter; import lombok.Setter; @Entity @Getter @Setter public class LikedItem { @Id @GeneratedValue @Column(name = "likedItem_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "item_id") private Item item; } 보시는 것처럼 멤버와 좋아요 상품은 Lazy 관계에 있습니다. OneToMany는 기본이 Lazy이므로 명시하지 않았습니다. 따라서 좋아요 상품은 직접 조회될 때만 DB에서 조회되고, 다른 경우는 프록시 형태로 존재합니다. //아이템 상세 정보 @GetMapping("item") public String itemDetail(@RequestParam("itemId") Long itemId, @SessionAttribute(name = "loginMember") Member loginMember, Model model) { log.info("item 호출"); Item item = itemService.findOne(itemId); log.info(loginMember.getLoginId() + " " + loginMember.getName()); // 좋아요 여부 추가 model.addAttribute("isLiked", memberService.isliked(loginMember, item)); //이 부분입니다!! model.addAttribute("item", item); model.addAttribute("member", loginMember); if (item.getCategory().equals("Book")) { return "items/item/book"; } if (item.getCategory().equals("Album")) { return "items/item/album"; } if (item.getCategory().equals("Movie")) { return "items/item/movie"; } return "items/item"; } 위 컨트롤러를 호출하면, isliked라는 매소드를 실행하게 됩니다. 좋아요 여부를 확인하는 메소드입니다. //좋아요 아이템이 아니면 false 반환 @Transactional public Boolean isliked(Member member, Item item) { log.info("좋아요 확인 메서드 실행"); // log.info("멤버 정보" + member.getName() + " " + member.getLoginId()); for (LikedItem likeditem: member.getLikedItems()) { //여기에서 lazyinitializationError 발생 if (likeditem.getItem().getName().equals(item.getName())) { log.info("좋아요인 경우"); return true; } } log.info("좋아요 아닌 경우"); return false; } 그런데 여기에서 맴버의 좋아요 목록을 불러오면 lazyinitialization 에러가 발생합니다... 정말 많이 원인도 구글링해보았는데, 영속성 컨텍스트가 종료 된 후 접근할 때 발생하는 것을 알았습니다. 영속성 컨텍스트의 생명주기는 트렌잭션과 거의 동일하다고 알고 있습니다. 만약 위 메소드에 트렌젝션 어노테이션이 없다면 member.getLikedItems() 의 결과를 초기화해주지 않으면 오류가 발생할 것입니다. 따라서 트렌젝션 어노테이션을 넣으므로서, member.getLikedItems()를 가져오고, 직접 DB에서 불러오는 과정을 한 트랜젝션 안에서 수행하도록 했습니다. 그런데 이 메서드에서 계속 LazyinitializatoinError가 발생합니다. 이 부분의 원인을 전혀 못 찾겠습니다.. 해결책으로는 DTO를 사용하거나, fetch Join을 사용해서 멤버와 같이 조인하여 한번에 가져옴으로 해결할 수있을 거라 생각합니다. 하지만 해결책은 알았지만, 위 코드의 무슨 오류가 있는지 정말 궁금합니다. 따라서 이 코드의 오류를 알고 싶습니다. 또한 저의 이해에 오류가 있다면 그 부분도 알려주시면 감사하겠습니다.