30%
61,600원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결실전! Querydsl
java: cannot find symbol
java: cannot find symbol가 나와서 빌드도 안되고 실행도 안되네요ㅠㅠ 어떤 이유일까요? 인텔리제이 18년도 버전은 되는데 20년도 버전은 안되네요....ㅜㅜ
- 미해결실전! Querydsl
안녕하세요. Repository에 대한 테스트 코드 작성에 관하여 문의드립니다.
안녕하세요. 영한님 항상 좋은 강의 제공해주시고 질문에 대해 친절히 답변해주셔서 감사합니다. QueryDSL로 코드를 작성하고 나서 Repository에 대한 테스트를 하기 위해 테스트코드를 작성할 시 궁금한 사항이 있어 문의드립니다. 1. 여러 엔티티가 연관관계가 맺어있는 상태입니다. 사용자 엔티티와 게시물 엔티티, 이미지파일 엔티티, 댓글 엔티티 등 2. 실무에서는 위의 예시보다 훨씬 더 복잡한 관계로 맺어있기 때문에 해당 기능을 테스트하기 위한 즉 stub 데이터가 많이 필요한 것으로 예상됩니다. 기능을 위한 테스트를 하기 위해 넣어야 할 데이터가 많은경우 기능을 테스트하는 것보다 데이터를 insert하는 코드가 많아져 번거로움이 발생할텐데 이럴경우 어떻게 대처하는지 궁금합니다.
- 미해결실전! Querydsl
Spring Data JPA와 Repository 구현 클래스 동시사용
안녕하세요. Spring Data JPA를 상속받은 Repository와 RepositoryCustom, RepositoryImpl가 존재하는데 Repository의 반환 Type이 해당 Entity라면 RepositoryImpl에서 구현한 메소드의 반환 Type 또한 해당 Entity로 반환해야하는건가요?? 이에 대한 해결책은 단순히 구현한 클래스를 사용하는 방법밖에 존재하지 않나요??
- 해결됨실전! Querydsl
테스트 관련 질문이 있습니다!
안녕하세요 강사님. QA관련 글들을 보다가 이 글을 보았는데요. https://www.inflearn.com/questions/42585.여기 글에 강사님이 남긴 답변중에 "@DataJpaTest는 기본적으로 JPA 테스트를 위한 최소한의 스프링 빈만 컨테이너에 로딩합니다. 제가 사용하는 빈들을 기본 설정으로 로딩하지 않습니다. 그래서 저는 실무에서 테스트를 작성할 때 @DataJpaTest를 잘 사용하지 않습니다. 실무에서는 이미 @SpringBootTest를 사용하고 있는데, 이렇게 추가 테스트가 들어가면 스프링 컨테이너가 추가로 한번 더 실행되어야 합니다." 라고 하셔서 질문이 있습니다!! 만약 100개의 테스크 클래스가 있다고 가정하면, 50개의 클래스에서는 @SpringBootTest를 사용하고, 20개는 @DataJpaTes, 나머지 30개는 순수 자바 or 목을 사용한다고 하면 테스트케이스를 전체 실행할때, 50개의 클래스마다 스프링 컨텍스트가 뜨고, 내리고 그리고 나머지 30개는 @DataJpaTest에 필요한 의존성만 받고, 내리고를 반복 하잖아요~~ 근데 강사님께서는 "한번 더 실행되어야 합니다." 라고 말씀을 해주셨는데 @DataJPaTest가 아닌 @SpringBootTest를 이용해도 스프링 컨텍스트가 한 번더 실행되고 내려가고를 반복해야하는 거 아닌가요??!! 제가 잘못알고있었던건지 혼란이 오네요! ㅠㅠ
- 미해결실전! Querydsl
2개 이상의 OneToMany 관계에서 fetch join 문제
안녕하세요 영한님! 좋은 강의 너무너무 잘 듣고 있습니다! 다름이 아니라 JPA와 Querydsl을 공부하던 중 궁금한 점이 생겨 이렇게 질문을 드립니다. OneToMany 관계에서는 N+1 문제를 해결하기 위해 fetch join을 사용해 자식 엔티티도 모두 함께 가져오는 것으로 배웠습니다. 만약 아래처럼 하나의 엔티티와 자식 엔티티, 자식 엔티티의 자식 엔티티가 모두 OneToMany 관계인 경우 최상위 엔티티를 가져올 때 한꺼번에 모든 자식 엔티티를 가져올 수 있는 방법이 있는지 여쭤보고 싶습니다..! @Entity public class Forest{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "forest_id") private Long id; @OneToMany(mappedBy = "forest") private List<Tree> trees= new ArrayList<>(); } @Entity public class Tree{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "tree_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "forest_id") private Forest forest; @OneToMany(mappedBy = "tree", cascade = CascadeType.ALL) private List<Leaf> leaves= new ArrayList<>(); } @Entity public class Leaf{ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "leaf_id") private Long id; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "Tree_id") private Tree tree; } 위 코드를 기준으로 제가 원하는 것은 모든 Forest을 가져올 때, Forest의 자식인 Tree와 Tree의 자식인 Leaf를 함께 가져오는 것인데, 처음엔 단순히 fetch join을 두번 사용하면 될 것이라고 생각했습니다. 따라서 코드를 다음과 같이 작성했습니다. public List<Forest> findAllFetch() { return queryFactory .selectFrom(forest) .leftJoin(forest.trees, tree).fetchJoin() .leftJoin(tree.leaves).fetchJoin() .fetch(); } 하지만 위 코드처럼 두개 이상의 OneToMany 관계에서 fetch join을 여러번 사용하면 MultipleBagFetchException이 발생했습니다. 찾아보니 JPQL에서는 xToMany에서는 일반적으로 fetch join은 한번만 허용된다고 하더라구요... 따라서 제가 생각한 해결책은 위 과정을 2번의 쿼리로 나누어 실행시키는 방법이었습니다. public List<Forest> findAllFetch() { List<Forest> result = queryFactory .selectFrom(forest).distinct() .leftJoin(forest.trees).fetchJoin() .fetch(); List<Long> selectedIds = result.stream() .map(Forest::getId) .collect(Collectors.toList()); queryFactory .selectFrom(tree).distinct() .leftJoin(tree.leaves).fetchJoin() .where(tree.forest.id.in(selectedIds )) .fetch(); return result ; } 혹시 위 코드보다 더 나은 방법이 있는지 아니면 한번의 쿼리로 모든 자식 엔티티를 받아올 수 있는 방법이 있는지 궁금합니다.
- 미해결실전! Querydsl
함수로 분리할 때 질문입니다.
안녕하세요. usernameEq(), ageEq()처럼 함수로 분리하니 메인 쿼리가 나가는 함수에서 실제로 가독성이 좋아지는걸 확인할 수 있었습니다. 여기서 질문이 한가지 있는데요. Querydsl강의는 아니고 타 강의였는데 DDD Aggregate root에 관한 이야기를 하신적이 있습니다. Post(글), Comment(댓글)로 예를 들자면 댓글의 경우 글에 종속되는 도메인 개념이기 때문에 PostRepository하나에 밀어넣는 방식을 선택할 수 있다고 들었습니다. 만약 Post, Comment 엔티티 모두에 같은 필드명인 username이라는 것이 존재하는 경우 함수의 네이밍과 분리를 어떻게 가져가야할까요? 1. postUsernameEq(), commentUsernameEq() 처럼 앞에 엔티티의 이름을 붙여서 분리한다. 2. usernameEq() 라는 하나의 함수를 만들고 인자로 엔티티를 함께 받아서 처리한다. (실제로 가능한지는 모르겠습니다) 이렇게 2가지의 방법을 생각해봤습니다. 이 부분에 대해서 영한님의 생각을 듣고 싶습니다. 감사합니다 :)
- 미해결실전! Querydsl
실무에서의 Projection 방식
안녕하세요. 실무에서는 프로퍼티 접근/필드 직접 접근/생성자/@QueryProjection 4가지 방식중 어떤걸 가장 많이 사용하나요? 상황에 따라 다르겠지만 일반적으로 실무에서 많이 사용되는 방법과 영한님의 생각을 듣고 싶습니다. 감사합니다.
- 해결됨실전! Querydsl
QueryDsl 1차 캐시관련
안녕하세요, 강사님! 강의를 복습하다가 궁금증이 생겨 질문 남깁니다. 조회된 엔티티는 영속화되며 1차 캐시에 저장이 되고 특별한 이벤트?! (EntityManager.clear() 또는 Transation이 종료 등등..)로 1차 캐시 내용이 없어진다고 이해하고 있습니다. 이렇게 이해한 내용 토대로 QueryDsl을 사용해도 1차 캐시를 사용하겠지라는 생각과는 다르게 동작하여 개념이 혼돈되고 있습니다. 아래 사진을 참고하시면 첫번째 쿼리를 실행후 그다음 쿼리 실행시 1차 캐시된 엔티티를 찾아 반환해 줘야하는데 다시 DB에 쿼리를 날려 결과를 가지고왔습니다. 제가 어떤 부분을 잘못 이해하고 있는 걸까요?
- 미해결실전! Querydsl
InitMember.class의 패키지 위치 질문있습니다.
영한님 안녕하세요. 덕분에 점점 JPA가 재밋어지고 최적화에 재미를 들이고 있습니다. 강의 중에 데이터를 초기화 하는 클래스를 main 패키지 하단에 두셧는데요. 보통 저런 데이터 초기화 클래스를 test 패키지에 안두고 main에 두어도 상관 없는지 궁금합니다. 실무에선 보통 저런 초기화 데이터를 실제 어떻게 만들고 관리하는지도 궁금합니다. 감사합니다.
- 미해결실전! Querydsl
17강 조인 - on절을 듣다가 질문드립니다.
안녕하세요. 스프링입문부터 강의를 듣다가 처음으로 질문드립니다. 17강 조인 - on절을 듣던중 join_on_filtering() Test예제에서 잘 모르겠는 부분이 있어서 질문드립니다. 모든 member를 조회하고 teamA이면 team을 left outer join 으로 조회하는 케이스였는데요 list<Tuple> result 를 loop한 결과 ``` tuple = [Member(id=3, username=member1, age=10), Team(id=1, name=teamA)] tuple = [Member(id=4, username=member2, age=20), Team(id=1, name=teamA)] tuple = [Member(id=5, username=member3, age=30), null] tuple = [Member(id=6, username=member4, age=40), null] ``` 이렇게 나왔습니다. 제가 여기서 3번째 항목(index 2)의 Team이 Null인것을 확인하여 결과를 화면에 찍어보다가 result.get(2).get(member).getTeam() 을 했을때 teamB에 대한 select query 없이 TeamB가 출력되는 결과가 나타났습니다. 1. query 결과상 team_id(FK)는 null 이 나왔는데 result.get(2).get(member).getTeam() 과 result.get(2).get(team) 의 차이가 궁금합니다. 2. teamA에 대해 select 했기 때문에 result.get(2).get(member).getTeam() 가 null 이 나오거나 구문을 수행하면 teamB에 대한 select query를 실행할줄알았는데, LAZY와 상관이 없는것인지, teamB에 대한 select query 없이 teamB에 대한 내용이 출력될수 있는지 궁금합니다. (select query가 없어서 영속성 컨텍스트 1차캐시에서 바로 불러온줄 알았는데 그 전에 teamB에 대한 조회쿼리가 없었습니다) ps1. p6spy query로그를 보았을때 궁금한점이 있습니다. ``` /* select member1, team from Member member1 left join Team team with member1.team = team and team.name = 'teamA'1 */ select member0_.member_id as member_id1_1_0_, team1_.team_id as team_id1_2_1_, member0_.age as age2_1_0_, member0_.team_id as team_id4_1_0_, member0_.username as username3_1_0_, team1_.name as name2_2_1_ from member member0_ left outer join team team1_ on (member0_.team_id=team1_.team_id and team1_.name=NULL); ``` 주석안에 쿼리는 parameter가 잘 나왔는데 밑에 실제 query에는 NULL로 나오고 실제 수행된 결과는 parameter가 잘 적용된 결과가 나옵니다. ㅎㅎ... ps2. 사내에서 주 RDBMS를 Oracle로 사용하고있습니다.(과거 Oracle ERP를 사용하면서 주 RDBMS로 선택했고, 현재 SAP ERP로 전환하였지만 Legacy System의 DB는 95% 이상 Oracle로 운영되고있습니다) 기존 Legacy는 거의 Mybatis로 query mapping을 하고있는데 orm을 처음 적용하여 개발을 진행해보려고 합니다. 현재 dialect로 Oracle10gDialect를 사용하여 실습중인데 실습한 내용을 바탕으로 실 운영환경에서 잘 적용할 수 있을지 걱정이됩니다.
- 미해결실전! Querydsl
alias 질문드립니다 !
안녕하세요. 비전공 개발공부 8개월차 주니어입니다. 먼저 정말 유익한 강의 감사드립니다. 제게 큰 도움이 됐습니다. 다름아니고 질문드릴게 있는데요, 퇴근 후 QueryDSL로 토이프로젝트를 하고있습니다. 일별 방문자 수와, 누적 방문자 수 통계를 구하고 있는데요. 우선 제가 작성한 쿼리입니다. SELECT SUM(R.C) FROM (SELECT COUNT(DISTINCT CLIENT_IP) AS C FROM REQUEST_LOG GROUP BY DATE(REG_DATE) ) AS R; 쿼리 의도입니다. 1. 로깅테이블(REQUEST_LOG)에서 일별로 그룹핑하고, 클라이언트 IP로 중복을 제거한 값을 구합니다. (일별 방문자) 2. 일별 방문자를 모두 더합니다. (누적 방문자) 이걸 QueryDSL로 옮기려니 표현식과 alias를 쓰기가 막막한 느낌이 있습니다. 제가 참고한 문서와 작성한 코드입니다. http://www.querydsl.com/static/querydsl/3.6.3/reference/ko-KR/html_single/#alias @Override @Transactional(readOnly = true) public Long allVisitors() { JPAQueryFactory queryFactory = new JPAQueryFactory(getEntityManager()); return queryFactory .select(requestLog.clientIp.countDistinct()) .from(requestLog) .groupBy(functionDate(requestLog.regDate)) .fetch() .stream() .reduce(0L, Long::sum); } private StringTemplate functionDate(DateTimePath regDate) { return stringTemplate("date({0})", regDate); } 결국 alias를 어떻게 쓸지 잘 알지 못해 우선 서브쿼리를 포기하고 단순 select 문으로 일별 방문자수를 구해온 후 어플리케이션에서 stream으로 일별 방문자수를 모두 더해 누적 방문자수를 구해서 구현했습니다. 근데 그냥 자바코드없이 QueryDSL만을 이용해서 쿼리한방에 끝내고 싶지만 방법을 잘 알지 못해 어떻게 해결해야 할지 계속 고민중입니다. 혹시 실례가 안된다면 간단한 예제코드나 힌트 좀 주실 수 있으실까요? 😥 전체적인 소스코드 주소입니다. https://github.com/shirohoo/Application-SubscribeTechBlogs
- 미해결실전! Querydsl
안녕하세요. 실무에서의 방식에 대해 궁금한 사항이 있습니다.
안녕하세요. 영한님 퀄리티 좋은 강의를 해주셔서 감사합니다. JPA를 이용한 개인프로젝트를 하는 중에 의문사항이 생겨서 질문드립니다. 실무 즉, 현업에서는 신규 기능개발을 할 때 스키마를 설계해야하는 경우라면 DB스키마를 먼저 설계하고 이에 맞게 Entity 도메인을 설계하나요??
- 미해결실전! Querydsl
혹시 JPA에서 table partition 을 관리할 수 있나요?
안녕하세요. 강의를 수강하고 있는 도중에 로그성 테이블에 대해서 table partition을 JPA를 통해 생성하고 관리할 수 있는지 궁금합니다. 인터넷을 찾아보니... EclipseLink 에서 table partition 을 지원한다고 하는데요.. spring data jpa 에서도 제공되는지 궁금합니다.
- 해결됨실전! Querydsl
Querydsl 사용 중 오류
query dsl 사용중에 다음과 같은 오류가 발생했습니다. 오류 1 . DataJpaTest org.hibernate.PersistentObjectException: detached entity passed to persist: 오류 2. JPS incremental annotation processing is disabled. Compilation results on partial recompilation may be inaccurate. Use build process "jps.track.ap.dependencies" VM flag to enable/disable incremental annotation processing environment. Annotation Processer는 체크되어있는 상태입니다. lombok을 최신버전으로 명시해줘도 해결되지 않았습니다. 하나의 dependency를 추가하면 정상 실행되는 이상한 현상(?)이 발생했습니다. 추가한 dependency를 삭제하면 여전히 실행되지 않았구요. (특정 dependency가 아니라 무엇이든 상관없었습니다.) => 질문을 올린 이후에 gradlew clean / build로 해결하였습니다. 저와 같은 현상을 겪는 분들이 많은 것 같아 질문은 삭제하지 않고 남겨두도록 하겠습니다. <gradle 파일> (일부러 h2 부분 주석처리 해놓았습니다.) plugins { id 'org.springframework.boot' version '2.4.4' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" id "io.franzbecker.gradle-lombok" version "3.0.0"}group = 'ShallWe'version = '0.0.1-SNAPSHOT'sourceCompatibility = '11'configurations { compileOnly { extendsFrom annotationProcessor }}repositories { mavenCentral()}dependencies { implementation 'junit:junit:4.12' compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2' compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'com.querydsl:querydsl-jpa' compileOnly 'org.projectlombok:lombok' runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'// runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok'// testImplementation 'org.springframework.security:spring-security-test' implementation('org.springframework.boot:spring-boot-starter-validation') testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' }}test { useJUnitPlatform()}//querydsl 추가 시작def querydslDir = "$buildDir/generated/querydsl"querydsl { jpa = true querydslSourcesDir = querydslDir}sourceSets { main.java.srcDir querydslDir}configurations { querydsl.extendsFrom compileClasspath}compileQuerydsl { options.annotationProcessorPath = configurations.querydsl} <application.yml> spring: output: ansi: enabled: always datasource: url: jdbc:mariadb://localhost:3306/shallwetest?useUnicode=true&characterEncoding=utf-8 username: username password: password driver-class-name: org.mariadb.jdbc.Driver jpa: hibernate: ddl-auto: update #create , create-drop , update , validate, none properties: hibernate: show_sql: true format_sql: true
- 미해결실전! Querydsl
queryDsl에서는 DATE 함수 지원 하지 않나요?
SELECT * FROM member AS m INNER JOIN history AS h ON (m.id = h.id) WHERE DATE(h.created_at) = DATE_ADD(CURDATE(), INTERVAL -1 DAY) 해당 쿼리문을 만들어야 하는데요... 지금 까지 제가 해본 것 입니다!!!! 함수 () { LocalDate minusDays = LocalDate.now().minusDays(1); DateTemplate<LocalDate> localDateDateTemplate = Expressions.dateTemplate(LocalDate.class, "DATE({0},'%Y-%m-%d')", subQEmrConsultationHistory.createdAt, ConstantImpl.create("%Y-%m-%d")); BooleanBuilder booleanBuilder = new BooleanBuilder(); booleanBuilder.and(localDateDateTemplate.eq(minusDays)); return queryFactory .from(qhistory) .join(qhistory.member) .where(booleanBuilder) } 이렇게 한번 해보았는데 당연히 안되었네요... 이방법이 아닌거 같은데요... 이 경우 어쩔수 없이 Mybatis로 가야하나요....
- 미해결실전! Querydsl
EntityManager Id(pk)값 부여 질문드립니다.
안녕하세요, 강의 잘 보고 있습니다. 질문을 드리고 싶어서요. Member memberA = new Member(); em.persist(memberA); 를 하면, Mysql의 IDENTITY 전략의 경우 영속성 컨텍스트에 memberA를 저장하려면 Id값이 필요합니다. 그래서 DB에 insert 쿼리를 날립니다. 그리고 DB에서 배정받은 pk값을 가져와 그제서야 영속성 컨텍스트에 (배정받은 pk값, memberA)의 형태로 저장을 하는데요. 질문 1. 그럼 영속성 컨텍스트 안에 있는 memberA 의 id필드에 pk값이 삽입되어 있는 건가요? 질문 2. 맨 처음 Member를 생성했던 Member memberA = new Member(); 에 있는 memberA의 id필드도 DB에 insert할 때 할당받은 pk값이 삽입되는 건가요?
- 미해결실전! Querydsl
영속성 컨텍스트 쿼리 질문 드립니다.
안녕하세요, 강의 잘 듣고 있습니다. 질문을 드리고 싶어서요. 영속성 컨텍스트에 엔티티A가 있다고 가정해 볼게요. EntityManager의 em.find()를 통해 엔티티A를 조회하면, EntityManager는 영속성 컨텍스트에 있는 엔티티A를 반환하고, 실제 DB에 select 쿼리는 날리지 않는걸로 알고 있어요. 그런데 queryFactory는 생성자 인자로 EntityManager를 받고 있음에도, 왜 해당 강의 7분 21초에서는 select 쿼리가 나가나요?? queryDSL은 EntityManager 차원의 find 실행이 아니고, JPQL 차원의 쿼리 실행이라, 무조건 쿼리가 나가는 건가요??
- 해결됨실전! Querydsl
동시성 처리가 된건지 모르겠습니다.
@Transactionalpublic boolean enrollCourse(String studentId, Long courseId){ Course findCourse = courseRepository.findById(courseId).get(); if(findCourse.getCurrentNumStudent() == findCourse.getMaxNumStudent()) return false; Student findStudent = studentRepository.findById(studentId).get(); StudentCourse studentCourse = new StudentCourse(); studentCourse.enrollCourse(findStudent, findCourse); findCourse.addCurStudentNum(); studentCourseRepository.save(studentCourse); return true;} service의 메소드 입니다. 위의 동시성 처리 시나리오는 수강신청 최대 인원(findCourse.maxNumStudent)이 50명이고 현재 신청인원(findCourse.currentNumStudnet)이 49명일 때 동시에 여러 학생이 수강신청을 할 경우의 동시성 처리입니다. false를 반환 받으면 controller에서 클라이언트로 신청할 수 없다는 메세지를 전달합니다. JPAQueryFactory는 Repository마다 생성하고 JPAQueryFactory에 초기화하는 EntityManager는 주입받아서 전체 Repository에 공통으로 사용하고 있습니다. @Transactional 에너테이션을 추가했고, JPAQeuryFactory를 사용했으므로 동시성 처리가 되고 있는 건지 궁금합니다. 더 생각 해 본것이 메소드에 synchronized 를 사용하는 것도 괜찮을 까요? 클라이언트의 요청마다 스레드가 생기는 것이니까 가능할 것 같다고 생각합니다. 또, 혼자서 개발할 때 동시성 처리를 테스트 할 수 있는 좋은 방법이 있는지 궁금합니다.
- 해결됨실전! Querydsl
DTO .as 질문
안녕하세요 영한님! 강의 영상 5:36 경에 new QMemberTeamDto 인자의 member.id처럼 필드명이 맞지 않는거를 as로 바꿔주셨는데 @QueryProjection 방법 특성상 생성자로 Dto를 만들어 select하는거라 타입만 맞으면 되지 않나요?? 만약 일부로 as를 사용하신거면 dto 안에 이러한 필드가 있다고 좀 더 명시적으로 나타내기 위한 장치인가요?
- 미해결실전! Querydsl
Dto안에 List<Dto> 조회하기
public class AaaDto { private long id; private List<BbbDto> bbbs = new ArrayList<>(); } AaaDto를 조회하려고 합니다. .select(Projections.fields(AaaDto.class, Aaa.id, Projections.fields(BbbDto.class, ) ) 이런식으로 구현을 해보니 BbbDto 는 List가 될 수 없다는 에러는 반환하더라구요. 이런 경우에 한번에 Dto로 만드는 방법이 있을까요? JPAExpressions으로 감싸서 select fetch를 해보려 하였지만 잘 안되네요,,, 조언을 구해보고자 질문 올려봅니다. 감사합니다.