안녕하세요, 예전에 수업들은 이후 한창 현업 중에 잘못 사용한 Case 이지만 , 왜 그럴까 디버깅도 좀 해보고 생각을 많이 해보다가 해결을 못하고 질문을 남기게 되었습니다. 그나마 관련이 있는 부분을 찾아서 남기게 되었습니다. 앱에는 Foo 라는 엔티티가 있고, 우선 다음과 같은 JPQL 쿼리를 발생시켰습니다. String jpql = "SELECT f.id FROM Foo f " + "WHERE f.name = :name " + "ORDER BY f.createdAt DESC" // id 라는 특정 칼럼 조회이므로 Type 을 명시하지 않고 Query 를 써야 하는게 맞지만, 잘못 사용해서 TypedQuery 를 사용함 List<Foo> fooList = em.createQuery(jpql, Foo.class).setParameter("name", name).getResultList(); 일단 예외가 나지 않고 fooList 라는 List 가 반환된다는 것도 신기했습니다. 정확한 이해를 하지는 못했지만 디버깅 해본 결과, CgLibAopProxy 클래스들을 타는걸보면, Lazy 로딩과 유사하게 CustomFoo extends Foo 와 같은 상속객체를 만들어서, id 만 채워준 후 List 에 넣어서 반환해주기 때문에 문법적으로 fooList 를 만들 때 오류가 발생하는게 아니구나 판단했습니다. (아닐 수도 있습니다.. 제 생각) 이후 fooList.get(index) 를 시도하면서 바로 Casting 예외가 발생하였습니다. (Long 객체를 Foo 객체로 Casting 할 수 없다) 신기해서 IntelliJ 에서 디버깅 하면서 확인했을 때, fooList 라는 List 안에 Foo 객체들이 들어 있지 않고, Long 객체들이 들어 있는 모습을 확인했습니다. 이거는 좀 매우 이상한게, 어쨌든 Foo 라는 Type 이 들어가게끔 선언된 List 에 어떻게 Long 객체들만 들어가 있을 수 있는지가 이해가 되지 않았습니다. createQuery() 함수와 getResultList() 함수간 복잡한 제네릭 관계들을 이해하기가 어려워서 이 부분을 이해하지 못한 것 같기도 합니다. 물론 TypedQuery 를 사용하지 않고 Query 를 사용하거나 DTO 를 통해 매핑해주는 것이 맞지만, 지금 상황 기준으로 어떠한 이유로 List 형성 중 에러가 나지 않은 것인지 또 어떻게 List<Foo> 안에 인텔리제이 디버깅 기준으로 Long 객체들이 들어가 있을 수 있는 것인지 궁금합니다 _----------------------------- 추가로 나중에 subQuery 안에서도 동일하게 사용이 되었는데, 이런 경우는 쿼리 결과를 반환해주지 않고 그냥 쿼리문을 만들 때만 사용되어서 그런지 아무 에러가 발생하지 않았습니다. SELECT SUM(~~.~~) from Bar bar WHERE bar.foo.id in ( SELECT f.id FROM Foo f ~~ )
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 스프링 부트를 사용한다면 yml로 환경설정하길 추천한다고 하셨는데요. yml에서 persistence unit name을 설정하려면 매우 복잡하기 때문에 스프링부트 도움 없이 em을 띄우려면 xml 파일을 쓰는 편이 좋다고 답변하신 걸 봤는데요. 그렇다면 yml로 설정 시 테스트 환경에서는 em을 어떻게 실행할 수 있나요? repository에서 정의한 api를 테스트 파일에서 사용하는 거라서 테스트 환경에서 em을 사용할 일이 없나? 싶다가도 그러면 em.flush() 이런 기능을 테스트 환경에서 쓸 수 없게 되잖아요? 애초에 테스트 환경에서 flush, clear는 쓰는 게 아닌건가요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. springfox 버전의 스웨거는 2020년 이후로 업데이트가 종료된 후로 springdoc의 스웨거를 사용하는데 (업데이트 지속) 어떤걸 의존성 추가해야하는게 맞는것일지 고민이 됩니다.
학습 관련 질문을 남겨주세요. 어떤 부분이 고민인지, 무엇이 문제인지 상세히 작성하면 더 좋아요! 먼저 유사한 질문이 있었는지 검색해 보세요. 서로 예의를 지키며 존중하는 문화를 만들어가요. 안녕하세요 선생님 강의 잘보고 있습니다. 질문드리고 싶은 부분은 강의에서 사용되는 아키텍처에 대한 것입니다. 레이어드 아키텍처라는것은 이해했지만, 패키지 구조가 생소해서 어떻게 구성되는지는 이해하기 어려운것 같습니다. 제가 아는 방식은 컨트롤러, 서비스, 리파짓토리, 도메인 패키지로 단순하게 작성하는 방법인데, 여기서 사용된 패키지 구성방식과 관련된 키워드나 레퍼런스를 얻을 수 있을가요?
게시글과 댓글을 매핑 하려고 하는데 게시글에 어떤 댓글이 달렸는지 조회 하기 위해 게시글 -> 댓글 OneToMany 단방향 매핑을 하려고 했더니, @OneToMany는 지양하라고 해서 댓글에 @ManyToOne 매핑을 하려고 했는데요. 이러면 댓글->게시글 단방향이 되는 것 아닌가요? 게시글에 어떤 댓글이 있는지 확인을 하고 싶을 뿐인데 ManyToOne을 지양하는 이럴 땐 어떻게 해야하는지 궁금합니다 .. 매핑이 아니라 차라리 int communitySeq 를 멤버 변수로 갖도록 하고 jpql에서 join문을 통해 데이터를 가져오는 것이 맞을까요??
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예 [질문 내용] 요새 너무 질문을 많이 하는 것 같네욤 ㅠㅠ 1대다 fetch join 에서 @OneToMany 밑에다가 @BatchSize를 설정해서 성능을 최적화하는 강의 를 이해했습니다. 그런데 궁금한게 생겼습니다. 예를 들어 A, B , C 가 1대 다 , 다대 1 이라고 치면 (C는 중간 테이블 ) A에서 C의 데이터를 가지고 오는데 이 경우에는 @BatchSize를 이용해서 성능을 최적화하는게 좋은 방식인가요? 예를 들면 A 에서 A.getBList(). getC.Name () 이렇게 할 때 A에서 B에 대한 쿼리는 Batch Size 를 통해서 줄일 수 있어도 getC 를 통해서 또 쿼리가 나가는데 .... 어떻게 보면 걍 B 의 리포지토리에서 @Query("select b from B join fetch C where b.a,id=:id) 이런 식으로 하는게 더 나아보이기도 하고요.. 어떤 식으로 하는 것이 더 효율적이라고 생각하시는게 궁금합니다!!!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) A. 네 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) A. 아니요 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) A. 네 [질문 내용] 테스트 코드 실행을 하면 OpenJDK 64-bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended 이 경고가 계속 뜹니다. https://www.inflearn.com/questions/917150/openjdk-64-bit-server-vm-warning 찾아보면서 이 답변을 따라해도 로그가 뜨지 않고 경고가 뜨는데 어떻게 해야하나요?
Member Entity @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Builder @AllArgsConstructor @ToString(of = {"id", "username", "age"}) @NamedQuery( name = "Member.findByAgeGreaterThanAndUsername", query = "select m from Member m where m.age > :age and m.username = :username" ) public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "member_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "team_id") private Team team; private String username; private int age; /** * 연관관계 편의 메서드 */ public void changeTeam(Team team) { this.team = team; team.getMembers().add(this); } } Team Entity @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @Builder @AllArgsConstructor @ToString(of = {"id", "name"}) public class Team { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "team_id") private Long id; @OneToMany(mappedBy = "team", fetch = FetchType.LAZY) @Builder.Default private List<Member> members = new ArrayList<>(); private String name; } MemberRepository public interface MemberSpringJpaRepository extends JpaRepository<Member, Long> { List<Member> findByUsernameAndAgeGreaterThan(String username, int age); @Query(name = "Member.findByAgeGreaterThanAndUsername") List<Member> findByAgeGreaterThanAndUsername(@Param("age") int age, @Param("username") String username); @Query(value = "select m from Member m") List<Member> findUsers(); @Query(value = "select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t") List<MemberDto> findMemberDtoWithJoin(); /** * fetch join -> new 프로젝션 예외 터짐 */ // @Query(value = "select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join fetch m.team t") // List<MemberDto> findMemberDtoWithFetchJoin(); @Query(value = "select m from Member m join m.team t") List<Member> findMemberJoinWithTeam(); } 질문 /** * join -> new 프로젝션 정상 수행 */ @Query(value = "select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join m.team t") List<MemberDto> findMemberDtoWithJoin(); /** * fetch join -> new 프로젝션 예외 터짐 */ // @Query(value = "select new study.datajpa.dto.MemberDto(m.id, m.username, t.name) from Member m join fetch m.team t") // List<MemberDto> findMemberDtoWithFetchJoin(); @Query 애너테이션에서 쿼리문을 작성할 때, new 연산자를 사용하여 dto로 변환하여 반환하려고 합니다. Member-Team을 join 후 new 연산자를 사용하여 dto는 정상적으로 반환이 됩니다. 근데 페치조인을 사용 후 new 연산자를 사용하면 아래 예외 가 터집니다. fetch join으로는 new 연산자 사용이 안 되는 이유를 알고싶습니다. 발생하는 예외 java.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@3d1b6816 testClass = study.datajpa.repository.springjpa.MemberSpringJpaRepositoryTest, locations = [], classes = [study.datajpa.DataJpaApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties .PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@1255b1d1, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@47da3952, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@28a0fd6c, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@5fb97279, org.springframework.boot.test.context.SpringBootTestAnnotation@3f26d230], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. persistence.xml 도 jpashop 으로 수정했는데도 메인이 안돌아갑니다.
안녕하세요. JPA를 사용하다 질문이 생겼습니다. 다음과 같은 예시를 들어보겠습니다. @Entity @Setter @Getter public class A { @Id @GeneratedValue private Long id; @OnetoOne @JoinColumn(생략) private B b; } @Entity @Setter @Getter public class B { @Id @GeneratedValue private Long id; } 위와 같이 엔티티가 존재한다고 해보겠습니다. 새로 DB에 A 객체를 저장하고자 합니다. 이 때, A a = new A(); 와 a.setB(b); 를 통해 b 객체를 매핑했다고 가정하겠습니다. 그런데, 이 때 매핑한 b 객체가 준영속 상태더라도 매핑이 잘 되어서 a객체가 db에 저장되는것을 확인했습니다 (b 객체는 이미 DB에 존재합니다. ) 이게 원래 잘 되는게 맞는지 조금 헷갈리는데, 준영속 상태더라도 b의 PK를 가져오는 것이기 때문에 문제가 없는것일까요?
========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 강의자의 로드맵대로 따라 강의를 순차적으로 진행하고있습니다. 로드맵에서 추천해주신대로 실전!스프링 부트와 JPA 활용1 을 선 수강하고 이번 기본편을 수강하려고 하는데 이전 강의인 활용1편에서 H2 DB와 intellij를 최신버전으로 설치해두어 그대로 사용하려고 하는데 오류가 발생해서 문의 드립니다. 프로젝트의 내용은 학습자료인 2024 최신버전으로 프로젝트 생성하기의 소스코드를 open project 하여 진행하였으며 h2 데이터베이스의 설정도 프로젝트 생성 설명에 나와있는대로 진행하였습니다. 2월 05, 2024 6:14:22 오후 org.hibernate.jpa.internal.util.LogHelper logPersistenceUnitInformation INFO: HHH000204: Processing PersistenceUnitInfo [name: hello] 2월 05, 2024 6:14:22 오후 org.hibernate.Version logVersion INFO: HHH000412: Hibernate ORM core version 6.4.2.Final 2월 05, 2024 6:14:22 오후 org.hibernate.cache.internal.RegionFactoryInitiator initiateService INFO: HHH000026: Second-level cache disabled 2월 05, 2024 6:14:23 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl configure WARN: HHH10001002: Using built-in connection pool (not intended for production use) 2월 05, 2024 6:14:23 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001005: Loaded JDBC driver class: org.h2.Driver 2월 05, 2024 6:14:23 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001012: Connecting with JDBC URL [jdbc:h2:tcp:// localhost/~/test ] 2월 05, 2024 6:14:23 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001001: Connection properties: {password=****, user=sa} 2월 05, 2024 6:14:23 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl buildCreator INFO: HHH10001003: Autocommit mode: false 2월 05, 2024 6:14:23 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PooledConnections <init> INFO: HHH10001115: Connection pool size: 20 (min=1) 2월 05, 2024 6:14:23 오후 org.hibernate.engine.jdbc.dialect.internal.DialectFactoryImpl constructDialect WARN: HHH90000025: H2Dialect does not need to be specified explicitly using 'hibernate.dialect' (remove the property setting and it will be selected by default) 2월 05, 2024 6:14:23 오후 org.hibernate.engine.transaction.jta.platform.internal.JtaPlatformInitiator initiateService INFO: HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) 2월 05, 2024 6:14:23 오후 org.hibernate.engine.jdbc.connections.internal.DriverManagerConnectionProviderImpl$PoolState stop INFO: HHH10001008: Cleaning up connection pool [jdbc:h2:tcp:// localhost/~/test ] 오류 메세지입니다.
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요. 1. 강의 내용과 관련된 질문을 남겨주세요. 2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요. (자주 하는 질문 링크: https://bit.ly/3fX6ygx) 3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요. (질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG) 질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요. ========================================= [질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예/아니오) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) [질문 내용] 여기에 질문 내용을 남겨주세요. 현재 테스트 코드를 실행하면 실행은 정상적으로 작동되는데 항상 drop sequence ~~가 뜨면서 테이블에 있는 값들이 전부 삭제되는데 왜그런걸까요? ddl-auto: create상태고 @Commit에노테이션은 붙여놓은 상태입니다.
자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]
안녕하세요 ~ 자바 개발자 경력자인데요. 먼저 그냥 코딩을 이때까지 해왔지만 이렇게 기초부터 차근차근 비유해주시면서 설명해주시니 다시 개념확립이 되는것같아 감사드립니다. 일단 제가 궁금한점이 SI 이나 이떄까지 회사 프로젝트를 다녀본결과 .. 예를들어 쿼리결과를 저장하고 , API 사용시 (요청 /결과) 모두 이때까지 VO 라는 클래스를 만들어 사용하고 보았는데요. 이전부터 DTO , VO 두개의 차이점의 개념은 알고 공부하고 알고는 있었느나 , 항상 이때까지 모든 프로젝트에서는 모든 클래스를 뒤에 UserVO , DetailVO ... 이렇게 사용하곤했는데요. 아직까지도 아직경험을 못해서그런지 VO vs DTO 개념이 확립이안되네요; 앞으로 프로젝트참여시 VO 를 DTO 라고 명칭만 바꿔서 사용하면될까요?
안녕하세요! 강사님 강의를 듣고 msa 적용하는 프로젝트를 진행중인데, 프로젝트 controller단 전역에서 발생하는 예외를 처리하고 싶어 @@RestControllerAdvice를 활용하려고 생각중입니다. msa에서 예외를 전역으로 처리하려면 gateway에서 @RestControllerAdvice를 활용해야 될까요? 아니면 각각의 마이크로서비스마다 @RestControllerAdvice를 활용해야 될까요? 둘중 어떤 설계가 더 효율적일지 답변주시면 감사하겠습니다 🙏 🙏
강의의 예제와 비슷하게, Item 과 Order 라는 엔티티가 있고 OrderItem 이라는 엔티티가 그 사이에서 "주문한 상품" 목록을 정의하고 있습니다. 이때 Order 는 일대다로 Set<OrderItem> 을 참조합니다. 그런데 회사에서 요구사항으로 Order 와 함께 각각 Item 의 서브타입인 Album, Movie, Book 정보를 모두 각각 조회해달라고 하는 상황입니다. OrderItem 은 Item 만을 가지고 있기 때문에 구체 클래스인 Album 등을 orderItem.getAlbum(); 처럼 가져오지 못 하는 상황인데, 이때 이를 가져올 수 있는 전략에는 어떤 것들이 있을까요? itemId 로 다시 repository 로 데이터를 가져온다. Item getItem = orderItem.getItem(); if (getItem.getType() == ALBUM) { Optional<Album> optAlbum = albumRepository.findById(getItem.getId()); } else if ... OrderItem 이 super 클래스가 아니라 sub 클래스를 참조하도록 한다. public class OrderItem { // ... @OneToMany(...) @JoinColumn(...) private Album album; @OneToMany(...) @JoinColumn(...) private Movie movie; // ... } 일단 생각나는 방법은 위 2개인데, 각각 단점이 있다고 생각해서 개인적으로는 만족하지 못 한 상황입니다. 일단 위 방법 중 1번 방법으로 데이터를 반환해주고 있는 상황입니다. 2번은 테스트도 안 해보긴 했지만, 저렇게 하면 안 될 것 같아서요. 맘 같아선 API 분리해서 던져주고 싶은데 그러지도 못 하는 상황이고 ... 그냥 마법 같이 내가 가져온 Item 이 Album 타입이면 알아서 Album 으로 조회한다든지, 그런 기능이 있었으면 참 좋겠다 싶은 생각이 드네요 아무튼, 이렇게 super class 를 필드로 가지는 엔티티가 그 super class 를, 타입에 따라 알맞는 상속 받는 sub 클래스를 가져오려면 어떤 전략이나 기능을 사용해야 하고, 어떤 것들이 고려되어야 할까요? 늘 좋은 강의 감사합니다.
[질문 템플릿] 1. 강의 내용과 관련된 질문인가요? (예) 2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예) 3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예) [질문 내용] 첫번째 캡쳐본의 경우에는 em.getReference(Member.class, member.getId()); 할 때 select 문이 실행되지 않았는데, 여기 두번째 캡쳐본의 경우에는 em.getReference(Member.class, member1.getId()); 할 때 select 문이 실행되는 이유가 궁금합니다.