묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
finditems() 에러
'테스트 - 스프링 부트와 임베디드 모드' 수강 중에 ItemRepositoryTest를 h2를 모두 끄고 동작시켰는데강사님처럼 모두 성공을 뜨지 않고 finditems()에서 에러가 납니다.강의자료 초반에 데이터베이스에서 데이터가 보관되어 있어서 그렇다고 들었는데어떻게 해결해야하나요?? h2는 접속 종료한 상태입니다.
-
미해결스프링 DB 2편 - 데이터 접근 활용 기술
IncorrectResultSizeDataAccessException
'JdbcTemplate 적용1- 기본' 강의에서 findById()를 설명하실때,'결과가 없을경우'는 catch로 예외처리를 해주시는데'둘 이상일 경우' IncorrectResultSizeDataAccessException에 대해서는 왜 catch문으로 예외처리를 하지 않는것인지 궁금합니다.
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
어그리거트 설계
jpa를 활용해서 어그리거트를 만들고 있습니다. 게시글 (post 어그리거트)게시자 (member 어그리거트)로 어그리거트를 나눴습니다. 그리고 프로젝트 패키지 구조는 이런 식 입니다.controller- post- memberservice- post- memberdomain (entity와 repository 인터페이스)- post- memberinfra (repository 구현체)- post- member 만약 같은 데이터베이스임에도 post엔티티가 member엔티티를 간접참조(Long memberId를 통한 참조)를 하고 있다면, post 상세페이지에서 member의 이름을 띄워주는 것을 어떻게 구현해야 좋을까요? 현재 고려하고 있는 방법은 두 가지 입니다.service/post 패키지에 PostDetailService 객체를 만든다. 그리고 이 객체가 postRepository와 memberRepository를 di 받은 다음에 두 엔티티를 가져오고 responseDto로 합쳐서 PostDetailController에게 리턴한다.이유는 member 어그리거트가 다른 서버로 분리될 경우, memberRepository의 구현체만 변경하면 될 것 같아서 입니다. (member의 서버가 다른 서버가 되면 member 정보를 api로 받아와야 할 것 같아서 그렇게 하였습니다.) 또 다른 방법으로는 현재는 같은 rdb에 저장되어 있으니 Dao객체를 만들어서 조인으로 responseDto를 직접 만드는 방법이 있을 것 같습니다. jpa 연관관계는 없으니 조인으로 쿼리를 날려야 할 것 같습니다. 어느 방법이 더 좋은 방법인가요? 혹은 더 좋은 방법이 있을까요?
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
DTO를 Result<T> 클래스에 담아서 반환할 때의 예외처리
안녕하세요!영한님 강의를 들으면서 추가적으로 RestTemplate에 대해 알게되어 지금까지 배운 것을 복습할 겸 api와 DTO 통신에 대해 연습하고 있었습니다.DTO를 반환할 때, 그냥 주기보다는 Result<T>의 data같은 속성에 담아서 주는 것이 바람직하다고 하여 그 응용을 연습해 볼겸 Result<T>에 status 속성을 추가해보았습니다.status 속성은 외부 api에서 조건을 충족하는 api를 찾아 와서 반환할 DTO가 있을 경우 "success"를, 조건을 충족하는 api를 찾지 못하여 HttpClientErrorException 예외가 발생할 경우 "fail"을 담아서 반환하고자 하였습니다.아래의 코드를 통해 구현은 성공하였으나, Service 클래스에서 try-catch문을 사용하는게 좀 찜찜하여 혹시 try-catch문 없이 구현하는게 더 좋을지 아니면 그냥 사용해도 좋은지가 궁금하여 질문을 하게 되었습니다.(status가 "fail"이면 data는 null을 반환하게끔 설계해보았습니다) @RestController @RequiredArgsConstructor @RequestMapping("/summoners") public class SummonerController { private final SummonerService summonerService; @GetMapping public ResponseEntity<Result<SummonerDTO>> findSummonerApi(@RequestParam String name) { SummonerDTO summonerDTO = summonerService.findSummonerApi(name); if (summonerDTO == null) { return ResponseEntity.ok().body(new Result<>("fail", null)); } return ResponseEntity.ok().body(new Result<>("success", summonerDTO)); } }@Slf4j @Service @RequiredArgsConstructor public class SummonerService { @Value("${apiKey}") private String apiKey; private final SummonerRepository summonerRepository; private final RestTemplate restTemplate; // riot에서 소환사 정보 api를 받아오는 메서드 public SummonerDTO findSummonerApi(String name) { String url = "https://kr.api.riotgames.com/lol/summoner/v4/summoners/by-name/{summonerName}"; HttpHeaders headers = new HttpHeaders(); headers.set("X-Riot-Token", apiKey); try { return restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(headers), SummonerDTO.class, name).getBody(); } catch (HttpClientErrorException e) { return null; } } }Controller와 Service의 코드는 위와 같습니다. (restTemplate은 별도의 설정파일에 빈으로 구현하였습니다)
-
해결됨스프링 DB 2편 - 데이터 접근 활용 기술
jpa_pdf 객체 조회 부분에서..
memberId를 파라미터로 받고 해당하는 단일 Member 객체를 반환하는 find 메소드와 연관지었을 때JOIN 뒤에 있어야 할 WHERE M.MEMBER_ID = ? 와 같은 where 절이 없는데.. 생략된 것인가요?
-
미해결
spring boot 3.x 업그레이드 후 querydsl transform 함수 작동이 안됩니다.
안녕하세요. spring boot 3.1.0 으로 업그레이드하여 hibernate 6.2.2 버전을 사용하고 있습니다.Querydsl 로 개발 도중 간단한 select 문은 정상적으로 작동이 되었는데,transform(groupBy().list()) 함수를 사용하니 에러가 발생하였습니다.java.lang.NoSuchMethodError: 'java.lang.Object org.hibernate.ScrollableResults.get(int)' at com.querydsl.jpa.ScrollableResultsIterator.next(ScrollableResultsIterator.java:70) at com.querydsl.core.group.GroupByMap.transform(GroupByMap.java:57) at com.querydsl.core.group.GroupByMap.transform(GroupByMap.java:35) at com.querydsl.core.support.FetchableQueryBase.transform(FetchableQueryBase.java:55) 버전 문제인 것 같아 spring boot 2.x 버전으로 내리고 hibernate도 5.x 버전으로 내리니 정상 작동하더라구요...spring boot 3.x 로 업그레이드하면서 transform() 함수가 제대로 동작을 안 하는 걸까요?
-
해결됨실전! Querydsl
로그에 native Query가 출력되게 하려면 어떻게 해야하나요?
요약QuerydslRepositorySupport 적용p6spy 적용쿼리 로그는 출력이 되고 있지만 native query로 출력되지 않음. 로그 예시-- 현재 출력되는 로그 포맷 select daOrder.id, daOrder.createDate from DaOrder daOrder -- 원하는 로그 포맷 select d.id, d.create_date from da_order d 로컬에서 네이티브 쿼리가 바로 로그에 보이도록 설정하고 싶은데테이블명이 아닌 클래스명으로 쿼리가 출력이 되고 있는데요 혹시 어떤 설정을 바꿔야하는지 알 수 있을까요??
-
미해결더 자바, 코드를 조작하는 다양한 방법
어노테이션 프로세서 활용 예와 관련해 질문 있습니다.
'마무리' 한 강 남았네요.덕분에 많이 배우고 많이 성장한 것 같습니다.그런데, 어노테이션 프로세서 활용과 관련해서,, QueryDSL 사용 시 생성되는 엔티티의 Q파일도 어노테이션 프로세서를 활용한 기술인지 궁금합니다.짐작으로는 맡긴 한데, 관련 언급이 없었어서요.
-
미해결실전! Querydsl
첫번째 querydsl테스트 코드 에서 nullpointexception이 터졌습니다
[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예/아니오)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오)[질문 내용]여기에 질문 내용을 남겨주세요.q타입을 생성하고 import를 해주었습니다. package study.querydsl; import com.querydsl.jpa.impl.JPAQueryFactory; import org.assertj.core.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; import study.querydsl.entity.Member; import study.querydsl.entity.Team; import javax.persistence.EntityManager; import static study.querydsl.entity.QMember.*; @SpringBootTest @Transactional public class QuerydslBasicTest { @Autowired EntityManager em; JPAQueryFactory queryFactory; @BeforeEach public void before() { Team teamA = new Team("teamA"); Team teamB = new Team("teamB"); em.persist(teamA); em.persist(teamB); Member member1 = new Member("member1", 10, teamA); Member member2 = new Member("member2", 20, teamA); Member member3 = new Member("member3", 30, teamA); Member member4 = new Member("member4", 40, teamA); em.persist(member1); em.persist(member2); em.persist(member3); em.persist(member4); } @Test public void startJPQL() { String qlString = "select m from Member m" + " where m.username = :username"; Member findMember = em.createQuery(qlString, Member.class) .setParameter("username", "member1") .getSingleResult(); Assertions.assertThat(findMember.getUsername()).isEqualTo("member1"); } @Test public void startQuerydsl() { Member findMember = queryFactory .select(member) .from(member) .where(member.username.eq("member1")) .fetchOne(); Assertions.assertThat(findMember.getUsername()).isEqualTo("member1"); } }
-
해결됨실전! Querydsl
jakarta 환경에서 javax 클래스패스로 entityManager를 찾고있습니다.
실행환경gradle 7.6.1java 17, jdk19spring boot 3.0.2제일 처음 환경을 설정한 후 테스트하는 코드에서 아래와 같은 로그가 발생합니다.java: cannot access javax.persistence.EntityManager class file for javax.persistence.EntityManager not found import static org.assertj.core.api.Assertions.*; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; import study.querydsl.entity.Hello; import study.querydsl.entity.QHello; @SpringBootTest @Transactional class QuerydslApplicationTests { @Autowired EntityManager em; @Test void contextLoads() { Hello hello = new Hello(); em.persist(hello); //현재 컴파일 에러가 나고 있는 부분 JPAQueryFactory query = new JPAQueryFactory(em); //em에서 javax.persistence.EntityManager 클래스를 찾을 수 없다는 에러가 나고 있음. QHello qHello = new QHello("h"); Hello result = query .selectFrom(qHello) .fetchOne(); assertThat(result).isEqualTo(hello); } }import문까지 모두 jakarta로 해주고 있습니다. 정상적으로 Q타입클래스가 되어있는데 JPAQueryFactory 생성자 부분의 에러가 전혀 사라지지 않습니다.버전문제인가 싶어서 여러번 버전을 확인했는데도, 제가 확인한 바로는 버전 호환에서는 문제 될 것이 없어보입니다.dataJPA가 3.0.X버전이상에서는 hibernate를 6+버전으로 맞춰줘야한다고 해서 확인해본 결과 hibernate는 다음과 같습니다.org.hibernate.orm:hibernate-core:6.1.7.Final추가적으로 build.gradle 코드를 올려놓겠습니다.plugins { id 'java' id 'org.springframework.boot' version '3.0.2' id 'io.spring.dependency-management' version '1.1.0' id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" } group = 'study' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.6' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' // == 스프링 부트 3.0 이상일 때, querydsl 의존성 == implementation "com.querydsl:querydsl-core:5.0.0" implementation "com.querydsl:querydsl-collections" implementation("com.querydsl:querydsl-jpa:5.0.0:jakarta") annotationProcessor "com.querydsl:querydsl-apt:5.0.0:jakarta" annotationProcessor "jakarta.annotation:jakarta.annotation-api" annotationProcessor "jakarta.persistence:jakarta.persistence-api:3.1.0" testImplementation ('org.springframework.boot:spring-boot-starter-test') testImplementation 'jakarta.persistence:jakarta.persistence-api' testImplementation 'com.querydsl:querydsl-jpa:5.0.0' } tasks.named('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 }
-
미해결실전! Querydsl
querydsl에서 oneToMany 관계인데 Many쪽 검색이 필요할 때 어떻게 해야하나요?
예를 들어 Order와 OrderItem이 있는데 Order의 검색을 동적쿼리로 검색해야해서 querydsl을 사용하고 있는 상황입니다. 그 중 검색조건이 OrderItem의 이름으로 검색해서 Order의 목록을 가져와야하는데 Order와 OrderItem을 조인하고 where절에 OrderItem의 이름으로 조회하는 방법 말고는 없을까요? 그럴 경우 distinct를 쓰거나 따로 중복 제거 로직을 넣어야해서ㅜ 혹시 다른 방법이 있나 문의드립니다.이런 경우에는 양방향 연관관계를 맺어주고 해결해도 될까요?
-
미해결실전! Querydsl
UPDATE 동적쿼리 사용 질문
안녕하세요. 강의 듣고 미니 프로젝트 하며 궁금한 점이 생겨 질문드려봅니다. UPDATE문에서도 동적쿼리를 사용하고 싶어 정적쿼리를 아래와 같이 구현해보았는데 혹시 WHERE절의 BooleanExpression처럼 조금 더 깔끔하게 처리할 수 있는 방법이 있을지 문의드려봅니다. 감사합니다.
-
미해결실전! Querydsl
중첩 객체 조회 관련
안녕하세요! querydsl 강의를 보고 실무에 적용 하던 중 중첩 객체에 대해서 한번의 join query로 만들 수 없을지 궁금하여 질문 드립니다. 만약, A -< B -< C (-< 은 one to many 를 의미) 관계를 가진 객체가 있다고 할 때selectFrom(A) .leftJoin(A.B) .leftJoin(A.B.C) .where(A.id.eq(1)) .fetch();위 코드의 반환 값이 아래와 같기를 희망 하는데요A = { id: 1, Bs: [ { id : 1, Cs : [ { id: 1 } ] } ] }oneToMany를 조인 하게 되면, SQL은 many의 row를 반환하게 되면서, A객체가 B의 갯수만큼 반환 되게 됩니다.group by등을 통해 해결 하려 했을 때는, oneToMany 컬렉션들이 모두 불러와지지 않는것을 확인 하였고, group by를 활용 하지 않고, 모든 row를 불러와서 aggregate하는 방식으로 코드를 구현 했습니다. 매번 쿼리문을 작성할 때 마다 aggregate하는 코드를 작성하는 것은 옳지 않을 것 같아, 혹시 더 나은 방법이 있을지 문의 드립니다. 혹시 중첩 쿼리를 join 으로 모두 찾아 객체에서 맵핑하려는 시도가 bad practice라면 쿼리 숫자가 늘어나더라도, findByAId, findByBId 등의 방식으로 여러번 쿼리를 하고, 중간에 캐시 레이어를 두는것이 더 나을지도 궁금 합니다. 항상 좋은 강의 감사합니다 :)
-
미해결실전! Querydsl
정적쿼리와 동적쿼리의 개념의 차이점이 궁금합니다.
Querydsl 기술은 복잡한 쿼리를 작성할 때나 동적쿼리를 쉽게 작성할 때 큰 강점을 가진 것으로 알고 있습니다. 그런데 정적쿼리와 동적쿼리의 개념에 대한 차이점이 잘 와 닿지가 않아 질문을 드립니다.정적쿼리에 파라미터를 주고 파라미터에 따라 쿼리를 한 결과가 달라지는 것은 왜 정적쿼리인 것인지 조금 혼란스러워서요.정적쿼리와 동적쿼리를 확실히 구분하는 기준(?) 같은 것이 있는지 궁금합니다. 여기서부터는 제 생각입니다!혹시 정적쿼리에 파라미터를 넣어서 조회하는 것은 파라미터를 넣지 않으면 아예 SQL이 실행이 되지 않는 반면에 동적쿼리를 수업에서 예시를 들어서 설명하신 것처럼 이름은 들어가고 나이는 들어가지 않아도 쿼리가 실행은 되는 그런 차이일까요?
-
미해결실전! Querydsl
JPQL vs Querydsl 강의 중에 startQuerydsl 테스트 코드 실행 시 에러질문이요
안녕하세요 JPQL vs Querydsl 부분 강의를 듣던 중에startQuerydsl() 테스트를 실행했는데 에러가 발생해서 질문 드립니다.현재 cannot find symbol class generated 에러가 발생합니다.검색 해본 결과Annotation Processor 문제 같아서Gradle Imported 에 있는 querydsl.main 폴더를Default 폴더로 이동 시켰습니다.현재 Default 폴더로 이동된 상황입니다.이후에 compileQuerydsl 을 빌드하고 다시 startQuerydsl()을 실행하면 동일한 에러가 발생합니다.그리고 gradle을 아예 새로고침하면querydsl.main 파일은 다시 Gradle Imported 로 돌아갑니다.. 현재 startQuerydsl 코드는 다음과 같습니다.@Test public void startQuerydsl() { JPAQueryFactory queryFactory = new JPAQueryFactory(em); QMember m = new QMember("m"); Member findMember = queryFactory .select(m) .from() .where(m.username.eq("member1")) .fetchOne(); assertThat(findMember.getUsername()).isEqualTo("member1"); } 또한 제가 Spring Boot 2.6 대 버전을 사용하고 있어서 build.gradle에 파일을 다음과같이 수정하고 아주 잘 돌아가는 상태였습니다.buildscript { ext { queryDslVersion = "5.0.0" } } plugins { id 'org.springframework.boot' version '2.6.13' id 'io.spring.dependency-management' version '1.0.15.RELEASE' //querydsl 추가 id "com.ewerk.gradle.plugins.querydsl" version "1.0.10" id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '1.8' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-web' //querydsl 추가 // implementation 'com.querydsl:querydsl-jpa' implementation "com.querydsl:querydsl-jpa:${queryDslVersion}" annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}" implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.8' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.h2database:h2' annotationProcessor 'org.projectlombok:lombok' // 이거 Settins 에 Annotation Processor 에 Enable annotation processing 체크 해야한다. testImplementation 'org.springframework.boot:spring-boot-starter-test' } tasks.named('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 } //querydsl 추가 끝 대체 왜 이런 에러가 발생하고 해결방법은 무엇일까요?감사합니다.
-
미해결실전! Querydsl
queryDsl vs @Query
안녕하센요 @Query를 사용해서 쿼리 사용하는것과 QueryDsl의 어떤 차이가 있는지 성능상 어떤면이 좋은지 알고 싶습니다
-
미해결실전! Querydsl
querydsl dto 변환시 Projection.fields * 전체 컬럼 가져오는 방법 문의 건
안녕하세요 강사님~ 엔티티 -> Dto 로 변환시 Projection.fields 사용할때 해당 컬럼 100~ 200 개가 있다면 명시하기 귀찮을 수 있는데요 컬럼하나하나 명시 하지 않고 엔티티 -> Dto 전체를 매핑 시킬 방법은 없을까요?
-
해결됨실전! Querydsl
offset과 distinct
팀과 멤버 (1:N) 팀 A의 멤버1, 멤버2, 멤버3, 멤버4, 멤버5가 있습니다. 팀A를 멤버와 함께 fetchjoin해서 가져오게 되면 팀A 객체 5개가 반환됩니다. 그런데 querydsl에서 아래와 같이 distinct()를 사용하지 않고 offset()만 사용하였는데 queryFactory .selectFrom(team) .join(team.members, member).fetchJoin() .offset(pageable.getOffset()) .fetch(); distinct 한 것처럼 중복이 제거되었습니다. 무슨 이유일까요?
-
미해결실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
querydsl 의존관계 없는 left join 문의
안녕하세요! 실무에서 jpa를 쓰게 되서 강사님의 책과 강의를 번갈아 보면서 열심히 개발하던 중에 궁금한 점이 있어 문의드립니다. 쓰다보니 query dsl이 참 편하더라구요! 그런데 연관관계 없는 두 개 entity를 조인해서 데이터를 조회해오고 싶은데, 아래와 같이 쿼리를 작성하니 실행 중에 QuerySyntaxException이 발생합니다. List<HistoryDto> historyList = queryFactory .select(Projections.fields(HistoryDto.class, pmntHistoryEntity.approvalNo, pmntHistoryEntity.approvalDate, pmntHistoryEntity.cancelType, pmntHistoryEntity.trxId, pmntHistoryEntity.trxReqDate, creditCardEntity.cardName, creditCardEntity.cardNumber )) .from(pmntHistoryEntity) .leftJoin(creditCardEntity).on(pmntHistoryEntity.cardToken.eq(creditCardEntity.cardToken)) .where( eqUserId(dto.getUserId()), eqOrderId(dto.getOrderId()) ) .fetch(); exception = QuerySyntaxException: begin 0, end -1, length 19 queryDsl에서 연관 관계 없어도 on 절을 통해 join이 가능한 것으로 알고 있는데 projection과 호환이 안되는 걸까요? 하루종일 구글링을 해도 나오질 않네요.. 혹시 알고 계시다면 답변 부탁드립니다 ㅠ_ㅠ
-
해결됨실전! 스프링 부트와 JPA 활용2 - API 개발과 성능 최적화
distinct중복 제거에 대한질문입니다!!
학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.=========================================[질문 템플릿]1. 강의 내용과 관련된 질문인가요? (예)2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (아니오)3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예)[질문 내용]친근하면서 알짜 베기 강의 너무 잘보고있습니다 다름이아니라 저도 항상 생각했던 문제인데 user team onetomany manytoone 일때 team10개를 가져올때 user 는 1개만 가져오고 싶을때 jpa에서는 distinct를 붙히면 해결된다고 강의에서 봤는데요 썡 쿼리랑 다르게 jpa distinct는 중복을 엔티티로 제거해준다고 봤습니다 다만 이방법이 querydsl에서도 가능한 방법인지 궁금합니다 물론 곧 영한 님의 querydsl도 수강예정입니다 ex) jpaQueryFactory.select(qatable,qbtable).distinct().from(qatable).on(뭐시기)~~~ 이런 상황에서도 distinct가 jpa방식으로 작동하는지 질문드립니다 감사합니다