월 17,600원
5개월 할부 시다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! 스프링 데이터 JPA
h2 데이터 베이스 연결하는데 오류가 있습니다
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]h2 데이터베이스를 연결하는 도중에 오류가 발생해서 질문드립니다 처음에 jdbc:h2:~/datajpa 이렇게 해서 연결을 성공해서 jdbc:h2:tcp://localhost/~/datajpa 이렇게 url을 입력을 해서 진행을 했는데 connen timed out이 발생을 합니다 datajpa.mv.db 생성된것도 확인을 하고 gitbash로 권한도 바꿔줬습니다!
- 미해결실전! 스프링 데이터 JPA
06:25~07:05 강의 내용 관련 디버깅 하다가 질문 있습니다
=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]안녕하세요! 강의 잘 듣고 있습니다.06:25~ 07:05 에서 설명하신 내용을 좀 더 파보기 위해서, 코드를 디버깅 하는 과정에서, 질문이 있습니다.(질문하고자 한 배경이 길어서, 질문의 내용은 맨 마지막에 있습니다!) => 설명해주신 내용을 제가 이해한 대로 적자면, "스프링 데이터 jpa는 NoResultException을 try-catch로 처리해서 null로 반환한다" 라고 이해했습니다.=> 그래서, 위 사진에서 breakPoint를 걸어서 F7로 저 메서드 내부를 파니까, 아래의 결과에서 해답이 있음을 유추했습니다=> 사진에서 retVal이 결국 null 값이며, 따라서 breakPoint인 retVal = invocation.proceed();에서, 강사님이 말씀해주신 "예외 처리 코드"가 있을 것이라고 생각했습니다. (질문)그런데 제가 위 breakPoint의 메서드를 F7로 들어가서 확인했는데 예외처리 코드 관련 부분이 어느 부분인지 잘 몰라서... 해당 부분을 어떻게 debugging으로 잡아낼 수 있을 지 문의드립니다.
- 해결됨실전! 스프링 데이터 JPA
DDD 적용시 JPA 설계에 대해 궁금한 사항
안녕하십니까 강사님. 좋은 강의 정말 감사합니다.이번에 강사님께 강의를 듣고 현업에 적용하는 도중 궁금한 사항이 있어 문의하게 되었습니다.저희는 현재 DDD 를 적용하려고 합니다. DDD 에서는 애그리거트끼리의 관계를 맵핑하는 것을 지양하는 것으로 알고 있습니다. 따라서 저희는 ERD 기준으로 도메인을 설계해보니 실제 나온 도메인을 보면 테이블이 전부 도메인 클래스가 되었고 서로간의 관계를 코딩으로 맺는 부분 (@ManyToOne 등)이 존재 하지 않습니다.현업에서도 ERD 를 기준으로 도메인 클래스를 나누면 테이블 당 하나의 애그리거트가 나오는 것이 보편적인 사항일까요?DDD 로 개발하다보면 도메인 클래스에 관계를 맺는 부분이 없는게 보편적일까요?
- 미해결실전! 스프링 데이터 JPA
Spring Data JPA delete 관련 질문
제가 따로 구현하지 않고Spring Data JPA JpaRepository 에서 상속받은deleteById 를 사용하면먼저 select query 가 1번 나간 다음에 찾아온 Entity로 delete 메서드를 호출하는 것 같더라구요그래서 총 select, delete 쿼리가 각각 1번 총 2번 나가는 것 같은데 PK로 delete 를 하고 싶을 때,@Query로 작성하여 delete 문을 1번 나가게 하는 것과,위의 방법대로 select, delete 각각 1번 나가는 방법 중에 어떤 방법을 사용하는 것이 좋은가요 ?
- 미해결실전! 스프링 데이터 JPA
페이지를 유지하면서 엔티티를 DTO로 변환관련하여 질문
스프링 데이터 JPA 페이징과 정렬 강의 부분에서페이지를 유지하면서 엔티티를 DTO로 변환하기Page<Member> page = memberRepository.findByAge(10, pageRequest); Page<MemberDto> dtoPage = page.map(m -> new MemberDto());페이지를 유지하면서 엔티티를 DTO로 변환하는 예제가 있습니다.만약에 아래와 같이 Page<Member> page = memberRepository.findByAge(10, pageRequest); List<Member> dtoPage = faqListPage.stream().map(MemberDto::new) .toList();List<> 로 반환하여 페이징 처리를 하였는데 페이지를 유지한 첫번째 방식 차이점이 있을까요??실무에서는 어떤 방식을 사용하나요?
- 해결됨실전! 스프링 데이터 JPA
[스프링 데이터 JPA 페이징과 정렬] left join 쿼리
MemberRepositorypublic interface MemberRepository extends JpaRepository<Member, Long> { List<Member> findMemberByUsernameAndAgeGreaterThan(String username, int age); ... @Query(value = "select m from Member m left join m.team t", countQuery = "select count(m.username) from Member m") Page<Member> findByAge(int age, Pageable pageable); } MemberRepositoryTestpackage hello.datajpa.repository; ... @SpringBootTest @Transactional @Rollback(false) class MemberRepositoryTest { @Autowired MemberRepository memberRepository; @Autowired TeamRepository teamRepository; ... @Test public void paging() { for (int i = 1; i <= 5; i++) { Member member = new Member("member" + i, 10); memberRepository.save(member); } int age = 10; PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username")); Page<Member> page = memberRepository.findByAge(age, pageRequest); List<Member> content = page.getContent(); long totalElements = page.getTotalElements(); int totalPages = page.getTotalPages(); int currentPage = page.getNumber(); boolean isFirst = page.isFirst(); boolean hasNext = page.hasNext(); assertThat(content.size()).isEqualTo(3); assertThat(totalElements).isEqualTo(5); assertThat(totalPages).isEqualTo(2); assertThat(currentPage).isEqualTo(0); assertThat(isFirst).isTrue(); assertThat(hasNext).isTrue(); } } Memberpackage hello.datajpa.entity; ... @Entity @Getter @Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) @ToString(of = {"id", "username", "age"}) /*@NamedQuery( name = "Member.findByUsername", query = "select m from Member m where m.username = :username" )*/ public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String username; private int age; @ManyToOne(fetch = LAZY) @JoinColumn(name = "team_id") private Team team; public Member(String username, int age) { this.username = username; this.age = age; } public Member(String username, int age, Team team) { this.username = username; this.age = age; changeTeam(team); } public void changeTeam(Team team) { if (team == null) throw new RuntimeException("Member.changeTeam: team is null"); this.team = team; team.getMembers().add(this); } } 쿼리select m1_0.member_id, m1_0.age, m1_0.team_id, m1_0.username from member m1_0 order by m1_0.username desc offset ? rows fetch first ? rows only select count(m1_0.username) from member m1_0강의와 다르게 left join을 해도 left join 관련 쿼리가 나가지 않는데 뭔가 강의와 다르게 설정된 부분이 있는 걸까요?@SpringBootTest @Transactional @Rollback(false) class MemberRepositoryTest { @Autowired MemberRepository memberRepository; @Autowired TeamRepository teamRepository; ... @Test public void paging() { Team team = new Team("A"); teamRepository.save(team); for (int i = 1; i <= 5; i++) { Member member = new Member("member" + i, 10); member.changeTeam(team); memberRepository.save(member); } int age = 10; PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Sort.Direction.DESC, "username")); Page<Member> page = memberRepository.findByAge(age, pageRequest); List<Member> content = page.getContent(); assertThat(team).isSameAs(content.get(0).getTeam()); // team == content.get(0).getTeam() ? long totalElements = page.getTotalElements(); int totalPages = page.getTotalPages(); int currentPage = page.getNumber(); boolean isFirst = page.isFirst(); boolean hasNext = page.hasNext(); assertThat(content.size()).isEqualTo(3); assertThat(totalElements).isEqualTo(5); assertThat(totalPages).isEqualTo(2); assertThat(currentPage).isEqualTo(0); assertThat(isFirst).isTrue(); assertThat(hasNext).isTrue(); } } 테스트 코드를 위와 같이 변경했을 때 left join 쿼리나 select 쿼리가 나가지 않고 assertThat(team).isSameAs(content.get(0).getTeam()) 테스트는 통과됩니다.위 코드는 이런 식으로 동작하는게 맞을까요?fetch join이 아니기 때문에 하이버네이트는 일단 member만 가져오는 쿼리를 날리고 레코드를 받아온다.받아온 레코드와 영속성 컨텍스트를 비교한다.받아온 레코드가 영속성 컨텍스트에 엔티티로 존재하므로 영속성 컨텍스트에 있는 엔티티를 반환한다.따라서 조회한 content.get(0) 객체에는 team 필드가 이미 할당 되어 있다.
- 미해결실전! 스프링 데이터 JPA
h2 데이터베이스 관련 문제
1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]질문 1)실전 스프링 Data JPA -섹션 1. 프로젝트 환경설정 -스프링 데이터 JPA와 DB설정, 동작확인 강의에서H2 데이터베이스 설치 후 , 동일하게 memberJpaRepositoryTest 한 후H2 데이터베이스 다시 접속하여 확인하여도 , member table 이 생성되어 있지 않습니다.콘솔창에 찍히는걸 봤을때는 insert까지 잘 된것을 확인했습니다만무엇이 문제일까요?[Member ].classpackage com.example.datajpa.entity; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import lombok.Getter; @Entity @Getter public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", nullable = false) private Long id; private String name; public Member(String name) { this.name = name; } //디폴트값으로 private 하기엔 프록시 생성시 사용되어야 함으로 protected 제어자를 통해 다른곳에서 만들지 못하도록함 protected Member() { } } [MemberJpaRepository] .class@Repository public class MemberJpaRepository { @PersistenceContext private EntityManager em; //jpa의 영속성컨텍스트를 관리 하는 엔티티메니저, 이것에 의해 데이터를 관리함. public Member save(Member member ){ em.persist(member);// 영속화 return member; } public Member find(Long id){ return em.find(Member.class,id); } }[MemberJpaRepositoryTest] .class@SpringBootTest @Transactional // 테스트가 끝난후 데이터를 롤백하기 위해 @Rollback(false) // 만약 롤백을 원하지 않을경우엔 이 어노테이션을 사용함, 실전에서는 ! 사용 노노! class MemberJpaRepositoryTest { @Autowired MemberJpaRepository memberJpaRepository; @Test public void testMember(){ //public 생략가능 Member member = new Member("memberA"); Member savedMember = memberJpaRepository.save(member); Member findMember = memberJpaRepository.find(savedMember.getId()); assertThat(findMember.getName()).isEqualTo(member.getName()); assertThat(findMember.getId()).isEqualTo(member.getId()); assertThat(findMember).isEqualTo(member); } } [application.yml]spring: datasource: url: jdbc:h2:tcp://localhost/~/datajpa username: sa password: driver-class-name: org.h2.Driver jpa: hibernate: ddl-auto: create # 객체를 보고 자동으로 테이블 생성 여부. 생성 - create, 비생성 - none # 테스트이기 때문에 create로 설정하며 # 실제로는 none 으로 합니다. create이면 기존의 테이블을 전부 밀어버립니다. properties: hibernate: show_sql: true format_sql: true logging.level: org.hibernate.SQL: debug # 콘솔창에 파라미터 값을 보고 싶을때 주로 개발할때, 실전에서는 성능저하 가능성 고려하여 사용해야함. org.hibernate.type: trace #implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7' 외부라이브러리 추가하면깔끔하게 파리미터값을 보여준다. # show_sql : 옵션은 System.out 에 하이버네이트 실행 SQL을 남긴다. # org.hibernate.SQL : 옵션은 logger를 통해 하이버네이트 실행 SQL을 남긴다. [build gradle]dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' //h2사용 runtimeOnly 'com.h2database:h2' [콘솔창]insert into member (id, name) values (default, ?) insert into member (id, name) values (default, 'memberA'); 2023-05-26 18:33:03.071 INFO 3250 --- [ main] p6spy : #1685093583071 | took 0ms | commit | connection 4| url jdbc:h2:mem:ca9facbe-0495-462f-a2eb-d8f9f1d14ecd ; 2023-05-26 18:33:03.072 INFO 3250 --- [ main] o.s.t.c.transaction.TransactionContext : Committed transaction for test: [DefaultTestContext@3b0c9195 testClass = MemberJpaRepositoryTest, testInstance = com.example.datajpa.repository.MemberJpaRepositoryTest@3f6a9ba0, testMethod = testMember@MemberJpaRepositoryTest, testException = [null], mergedContextConfiguration = [WebMergedContextConfiguration@366c4480 testClass = MemberJpaRepositoryTest, locations = '{}', classes = '{class com.example.datajpa.DataJpaApplication}', contextInitializerClasses = '[]', activeProfiles = '{}', propertySourceLocations = '{}', propertySourceProperties = '{org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true}', contextCustomizers = set[org.springframework.boot.test.autoconfigure.actuate.metrics.MetricsExportContextCustomizerFactory$DisableMetricExportContextCustomizer@5c86dbc5, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizerFactory$Customizer@5f9edf14, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@a8ef162, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@78fa769e, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@536dbea0, org.springframework.boot.test.context.SpringBootTestArgs@1, org.springframework.boot.test.context.SpringBootTestWebEnvironment@6b26e945], resourceBasePath = 'src/main/webapp', contextLoader = 'org.springframework.boot.test.context.SpringBootContextLoader', parent = [null]], attributes = map['org.springframework.test.context.web.ServletTestExecutionListener.activateListener' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.populatedRequestContextHolder' -> true, 'org.springframework.test.context.web.ServletTestExecutionListener.resetRequestContextHolder' -> true, 'org.springframework.test.context.event.ApplicationEventsTestExecutionListener.recordApplicationEvents' -> false]] 2023-05-26 18:33:03.096 INFO 3250 --- [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2023-05-26 18:33:03.097 INFO 3250 --- [ionShutdownHook] .SchemaDropperImpl$DelayedDropActionImpl : HHH000477: Starting delayed evictData of schema as part of SessionFactory shut-down' 2023-05-26 18:33:03.101 INFO 3250 --- [ionShutdownHook] p6spy : #1685093583101 | took 2ms | statement | connection 5| url jdbc:h2:mem:ca9facbe-0495-462f-a2eb-d8f9f1d14ecd drop table if exists member CASCADE drop table if exists member CASCADE ; 2023-05-26 18:33:03.106 INFO 3250 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2023-05-26 18:33:03.115 INFO 3250 --- [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. Process finished with exit code 0 질문 2. 이 강의를 보기 전에는 h2데이터베이스 별도 설치 없이아래와 같이 Application.yml 설정과Build.gradle에 의존성만 지정하여브라우저에서 Localhost:8080/h2-console 치면 h2 데이터베이스를 사용할 수 있었습니다.하지만 이 강의를 따라 h2 설치 후엔 Localhost:8080/h2-console 해도 500에러만 발생합니다. 이유가 뭘까요 ㅠㅠ[application.yml]# h2 datasource: driver-class-name: org.h2.Driver url: jdbc:h2:mem:db;MODE=MYSQL; username: sa password:[build gradle]dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' //h2사용 runtimeOnly 'com.h2database:h2'
- 미해결실전! 스프링 데이터 JPA
select 절에 조건식을 넣는 방법
강사님, 궁금한게 있습니다.select 절에 조건식을 넣고 싶은데 어떻게 해야 할까요?예)select start_post_dt, end_post_dt, news_title (now() >= start_post_dt and now() <= end_post_dt) as DateInRangefrom dummy_table;
- 미해결실전! 스프링 데이터 JPA
MemberTest
MemberTest에서 changeTeam메소드를 테스트 해보고 싶어서 추가로 코딩해서 실행해보았습니다.근데 System.out.println(member1.getTeam().getName()); System.out.println(teamB.getMembers().stream().collect(Collectors.toList()));위의 코드에는 반영이 되는 데 h2에 select문으로 member를 쿼리해보면 반영이 안되어있더라구요. 제가 공부한바로는 em.flush(), em.close 하면 db에 반영되는 걸로 이해하고 있는데... 잘못이해하고 있는 건가요??
- 미해결실전! 스프링 데이터 JPA
영속성 컨텍스트와 데이터 베이스 동기화
안녕하세요 공부를 하던 중에 궁금한 점이 생겼습니다.제가 간단한 회원정보를 스프링 데이터 jpa로 저장을 했는데 그 후에 db에서 직접 값을 바꾸고 조회하니 당연히 영속성 컨텍스트에 있는 부분과 동기화가 안되어 원하는 값이 조회가 안됐습니다. 이런 경우에 바뀐 값을 조회하려면 memberservice 혹은 JpaRepostory를 상속받은 memberRepository에서 영속성 컨텍스트를 clear로 한 번 지워야 할 것 같은데 어떻게 해야 할지 잘 모르겠습니다.
- 미해결실전! 스프링 데이터 JPA
외래키가 없는 경우 조회
안녕하세요.강의를 통해서 많은 도움을 받고 있습니다.궁금한 내용은 외래키가 없는 경우의 데이터 조회입니다. 예를 들어서 <주문> 할 때에 <회원 정보>를 외래키로 넣으면 문제가 없는데...비회원 주문을 할 경우에는 <주문> 테이블에 들어갈 회원 컬럼에 null 값이 들어가게 됩니다.그러면 조회할 때 아주 조회가 안되는 문제가 있더라구요.실행되는 퀴리를 보면 inner join으로 나옵니다.예상에는 left join 하는 것처럼 빈 칸으로 나오리라 생각하는데 말이죠. 이럴 경우에는 어떻게 해야 할까요?어떻게 해야지 비회원 주문과 같이 외래키가 없는 경우에도 조회 할 수 있을까요?
- 미해결실전! 스프링 데이터 JPA
엔티티 매니저에 대해!!!!
[벌크성 수정 쿼리] 강의 11:20쯤에"같은 트랜잭션이면 같은 엔티티 매니저를 불러온다"라고 강사님이 언급을 하셨습니다.질문 : 엔티티 매니저는 싱글톤 객체처럼 딱 1개만 가지고 재활용하면서 사용하는 것이 아니라, 트랜잭션이 실행될 때[마다] 새로운 엔티티 매니저가 생성되는 건가요??
- 미해결실전! 스프링 데이터 JPA
member 테이블에 member!!!!!!!!!이 안나옵니다.
member 에 저장된 데이터가 없습빈다.
- 미해결실전! 스프링 데이터 JPA
메소드 이름으로 쿼리 생성 - 내부 동작
안녕하세요, [메소드 이름으로 쿼리 생성 메소드] 강의 중 메소드 이름을 분석해서 JPQL 쿼리 실행 부분에 질문이 있습니다. 예를 들어 findByUsernameAndEmail()과 같이 이름을 정의하였을 때, 내부적으로 SQL을 어떻게 생성하는지 궁금합니다. '자바 ORM 표준 JPA 기본편' 강의에서 em.persist()를 실행하면 영속성 컨텍스트 내부에서 SQL을 생성하고, SQL 쓰기 지연 저장소에 저장하는 것을 설명해주셨습니다. 즉, 컴파일 시점이 아닌, 런타임 시점 동적으로 쿼리를 생성하는 것으로 이해하였습니다. 위에서 말씀 드린 findByUsernameAndEmail()과 같은 경우 jpql로 변환되어서 쿼리가 실행된다고 말씀해주셨습니다. 어떠한 방법을 통해, 내부적으로 어떠한 로직을 거쳐 런타임에 jpql로 변환이 될 수 있는지 궁금합니다. 감사합니다.
- 해결됨실전! 스프링 데이터 JPA
편의성 메소드에 대한 질문입니다.
jpa 강의들을 보다보면entity 간에 양방향 연관관계를 설정한 경우위처럼 changeTeam 메소드를 추가 해주셨는데요.this.team = team; 의 경우 외래키(연관관계 주인) 이기 때문에 필요한 것은 이해를 했습니다. 그런데 team.getMembers().add(this); 부분의 경우기존에 member 테이블에 값들이 존재하고, 신규 회원이 새로운 트랜잭션에서 join 로직을 실행했을때, 해당 로직에서 생성된 team.members에는 기존의 member 값들은 add 되어있지 않은 상태일텐데, team.members를 제대로 사용이 가능한가 해서 질문드립니다. 제 생각에는 team.members를 정상적으로(?) 사용하려면 team과 member를 join 으로 가져 온뒤에 사용이 가능할 것 같습니다. list에 add 하는것만으로는 query가 발생하는게 아닌것으로 알고있습니다. 제가 이해를 잘 못 하고 있는 부분이 있는걸까요?아니면 단순히 편의성 메소드의 예시로 작성을 하시는건지 궁금합니다.
- 미해결실전! 스프링 데이터 JPA
@Param의 존재 이유>?
@EntityGraph(attributePaths = "team") List<Member> findEntityGraphByUsername(@Param("username")String username);이번 강의를 복습하다 보니까 강사님께서 @Param을 사용하셨더라구요.(강의 20:59)findByAge(), findOptionalByUsername()과 같은 메소드는 @Param 애노테이션 없이도 잘 동작 했는데 따로 특별한 이유가 있는 것일까요?
- 해결됨실전! 스프링 데이터 JPA
@GeneratedValue 질문하고싶어요
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.1. 강의 내용과 관련된 질문을 남겨주세요.2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.(자주 하는 질문 링크: https://bit.ly/3fX6ygx)3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오) 네2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)네3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]@GeneratedValue에서 지금은 autoincrement로숫자로 단순히 pk값이 1/2/3/4이런식으로 사용되고있는데MEMBER00001/MEMBER00002/MEMBER00003같이 PK값에 특정한 문자열이 앞에 들어가는경우는 어떻게하나요?
- 미해결실전! 스프링 데이터 JPA
지연로딩과 fetchJoin 성능 차이
즉시로딩을 사용하면 Member 객체를 불러 올 때 1+N문제가 발생하고 Lazy로딩을 사용하면 Team 객체를 사용할 때 쿼리문이 나가서 즉시로딩이든 지연로딩이든 결국 1+N 문제가 생기는 게 맞나요 ? 이 1+N 문제의 해결방법으로 fetchJoin이 나온 것 같은데 지연 로딩, 즉시 로딩보다 무조건 fetchJoin이 이점이 있는 것 아닌가요? 왜 디폴트값으로 지연로딩으로 설정하고 fetchJoin을 선택해서 사용하는지 궁금합니다. 기본적으로 fetchJoin을 사용하고 연관관계에 있는 객체를 사용하지 않을 것 같은 경우에만 지연로딩을 선택적으로 사용하는게 더 편하지 않나요? 사용하지 않는 객체를 가져오는 fetchJoin의 쿼리문 몇 줄이 성능에 그렇게 큰 영향을 미치나요?
- 미해결실전! 스프링 데이터 JPA
2분 정도에 이 코드는 안되는 이유가 있나요?
Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); teamRepository.save(teamA); teamRepository.save(teamB); memberRepository.save(new Member("member1", 10, teamA)); memberRepository.save(new Member("member2", 10, teamB)); 강의에서 이렇게 한번에 하려다가 Member를 생성해주고 따로 save를 해주던데 한번에 하면 안되는 이유가 있을까요 ?
- 미해결실전! 스프링 데이터 JPA
Page 자료구조에 관해 질문입니다.
PageRequest pageRequest = PageRequest.of(0, 3, Sort.by(Direction.DESC, "username")); int age = 10; //when Page<Member> page = memberRepository.findByAge(age, pageRequest);PageRequest.of 코드에서 첫 번째 파라미터가 무엇을 의미하는지 헷갈립니다.PageRequest.of 의 2번째 파라미터는 한 페이지의 element 개수이고(limit), 3번째 파라미터는 정렬 조건이 맞나요?List<Member> content = page.getContent(); assertThat(content.size()).isEqualTo(3); assertThat(page.getTotalElements()).isEqualTo(5); assertThat(page.getNumber()).isEqualTo(0); assertThat(page.getTotalPages()).isEqualTo(2); assertThat(page.isFirst()).isTrue(); assertThat(page.hasNext()).isTrue(); page.getContent()는 현재 페이지의 데이터를 가져오는 메소드인가요?page.getNumber()는 현재 페이지를 가져오는 메소드인가요?Page는 책처럼 0,1,2,3 ... 이렇게 페이지가 있는 거고Content는 그 Page안에 있는 데이터를 의미하는 건가요? List<List<data>> 와 같은 구조로 되어 있는 것일까요? Page와 Content의 자료 구조가 어떻게 되어있는지가 궁금합니다.