@Query(nativeQuery=true,
value="SELECT * FROM question ORDER BY random() LIMIT 10")
DB will order all records before return one item.
So it's expensive in large data sets.
→ Error 발생
hashtag 중간 테이블 때문일 수 있을 것 같다.
Resolved [org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON: failed to lazily initialize a collection of role: capstone.be.domain.diary.domain.Diary.hashtags, could not initialize proxy - no Session; nested exception is com.fasterxml.jackson.databind.JsonMappingException: failed to lazily initialize a collection of role: capstone.be.domain.diary.domain.Diary.hashtags, could not initialize proxy - no Session (through reference chain: capstone.be.domain.diary.domain.Diary["hashtags"])]
Hibernate:
//
쿼리를 다음과 같이 바꾸어 실행해보았다. 다시 에러가 발생했다.
hashtag를 lazy fetching 이 아닌 JOIN문을 써서 Eager Fetching하는 방법이라 하는데 diary_hashtag중간 테이블이 있는 것으로 아는데 query를 다르게 다시 시도해봐야할 것 같다.
@Query(nativeQuery = true, value = "SELECT d.*, h.* FROM diary d LEFT JOIN hashtag h ON [d.id](http://d.id/) = h.diary_id ORDER BY RAND() LIMIT 1")
Diary findRandom();
>
Unknown column 'h.diary_id' in 'on clause'
2023-06-28 14:46:17.826 ERROR 16456 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessResourceUsageException: could not extract ResultSet; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not extract ResultSet] with root cause
java.sql.SQLSyntaxErrorException: Unknown column 'h.diary_id' in 'on clause'
hashtag때문에 에러나는 것 같아
hashtag를 담지 않는 DTO에 쿼리 결과를 담아 반환해보고자 했다.
그러나 또 다른 종류의 에러가 발생했다.
[Request processing failed; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found
capable of converting from type [org.springframework.data.jpa.repository.query.
AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [capstone.be.domain.diary.dto.DiaryRandomDto]] with root cause
org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type [capstone.be.domain.diary.dto.DiaryRandomDto]
diary조회할때 JPA에서 생성하는 쿼리를 그대로 사용하여 다시 실행해보고자 한다.
그냥 다른 방식으로 해봐야하나?
Find total of records from where you will select one.
Get one random item in this set.
'레코드를 하나의 페이지당 1개의 게시글을 가지도록 분할하고,
그 중 랜덤한 하나의 페이지만 골라오는 것이다
public Question randomQuestion() {
Long qty = questionRepository.countAll();
int idx = (int)(Math.random() * qty);
Page<Question> questionPage = questionRepository
.findAll(new PageRequest(idx, 1));
Question q = null;
if (questionPage.hasContent()) {
q = questionPage.getContent().get(0);
}
return q;
}
text를 받아야 하는데 저장할 때 text가 들어있는 데이터를 안 넣어서 발생했다.
id로 검색하는데 id 1부터있으니까 random에서 0~ cnt-1까지로 조회하면 0일떄는 에러나겠네
pageRequest는 zero-based라 랜덤할떄 +1안 해도 되네