본문 바로가기

trouble shooting/spring11

Myreview 조회 (성능개선) 성능 개선 전 service 로직 review를 불러오고 responseDto에 theme정보를 담을때 theme정보를 불러와서 N + 1문제 발생 select 쿼리가 3번 실행됨 성능 전 시간 63ms Querydsl projects, join 기능으로 성능 개선 후 service 로직 간소화 repository repository 와 service에서의 역할 분리 하나의 select query 실행 성능 개선 후 시간 49ms 성능 개선 전 63ms -> 성능 개선 후 49ms 단축 2022. 12. 12.
메인 페이지(명예의 전당) 추가 개선 사항 문제 상황 - Querydsl query projection 적용 후 select 쿼리가 3번 실행되는것을 발견 함 문제 원인 select 쿼리가 3번 날라가기 때문임을 발견 함 문제 해결 select 쿼리를 합치고 List의 size를 담아주는 totalSize변수를 없애고 result의 크기를 그대로 반환하였다. 개선 후 실행 쿼리 select query 딱 한번 실행됨 개선 전 postman 개선 전 속도 36ms 개선 후 postman 개선 후 속도 27ms 문제 해결 후 알게 된 점 1. Querydsl으로 select를 할때 select할때마다 query가 실행 된다는 것을 알게되었다. 2. 쿼리가 여러번 실행되면 확실히 성능에 문제가 생긴다는 것을 알게되었다. 2022. 12. 12.
querydsl query projection 사용 (메인 페이지 명예의 전당) 문제상황 - 명예의 전당 API serivce로직이 길어지는것을 최소한 간소화 하고싶었음 문제 원인 개선 전 service 로직 개선 전 repository @Buider를 사용하게 되서 service로직이 길어지게 되었다. 문제 해결 Querydsl 의 Projections기능을 사용함 개선 후 service 로직 개선 후 repository 문제 해결 후 알게된 점 1. service단 코드가 간결해졌다. 2. DB작업이 일어나는 부분이 전부 repository에서 실행되기 때문에 MVC 패턴에서 Model(데이터 처리), view(사용자가 보는 페이지) 그리고 Controller(model, view를 제어) 가 깔끔하게 분리되었다. 3. MVC패턴의 장점중에 유지보수성, 중복코딩감소 적인 측면에서.. 2022. 12. 12.
@Transaction 오류 미니 프로젝트와 클론 프로젝트 그리고 주특기 공부할때 기술멘토님들에게 계속 강조를 받았던 @Transaction에 관한 에러가 나왔다. 1. 문제 상황 - 변경 감지 기능을 사용해서 특정 데이터를 db에 저장하려고 했는데 계속 해서 db에 값이 저장이 안되었다. - 코드는 문제가 없다고 판단했지만 코드를 수정하는것 말고는 딱히 해결방법도 못찾았다. 위에서 분명히 member를 모두 불러왔고 그렇기때문에 변경 감지 기능을 사용하면 save하지 않아도 값이 잘 저장되어야 하는데 계속 db에 값이 저장되지 않았다. 2. 문제 원인 조회하는 로직이라고 생각하고 @Transaction이 원래 빠져있었기 때문에 @Transaction(readOnly = true) 값이 적용되고있었던 것이다. 그래서 값이 수정이 되.. 2022. 12. 7.
쿼리 성능 개선(메인 페이지 업적 조회) 문제상황 - JPA로 코드를 짰을때 N + 1 문제가 발생 - 회원의 메인 업적 조회하는 부분에 쿼리가 8번 실행됨 - builder를 사용함으로 인해서 service로직이 길어지는 것을 최대한 줄여보고 싶었음 PostMan으로 테스트 했을때 동작하는 쿼리 Main achieve service 로직 문제 해결 2022. 12. 5.
실전 프로젝트 service 로직 개선 사항 문제 상황 - 현재 service의 method에서 핵심적인 로직이 무엇인지를 판단하여 부가 로직은 따로 빼서 method화 하거나, aop, util class등으로 분리시키시면 좋을 것 같다는 멘토님 피드백. - 예를 들면, badgeService에서, createBadge()를 보았을 때 핵심적인 기능은 badge를 생성하여 db에 저장하는 기능이다 . 그런데 현재 s3에 사진을 올리는 기능이 섞여있다 보니, 너무 코드가 복잡하기도 하고, 다른 곳에서 사진 올리는 기능을 사용하려고 할 때, 똑같이 작성해야 한다. 문제 원인 1. 테마 정보를 DB 저장하는 메서드 인데 그 사이에 S3 사진 저장하는 기능이 추가되어있어서 지금 현재 이 service에서 어떤 로직이 수행되는지 불분명하고 복잡함. 2. .. 2022. 12. 2.
@Transactional(readOnly = true) 읽기 전용 쿼리의 성능 최적화 엔티티가 영속성 컨텍스트에 관리되면 1차 캐시부터 변경 감지까지 얻을 수 있는 혜택이 많다. 하지만 영속성 컨텍스트는 변경 감지를 위해서 스냅샷 인스턴스를 보관하므로 더 많은 메모리를 사용하는 단점이 존재 한다. 만약 조회만 하는 경우에 읽기 전용으로 엔티티를 조회하면 메모리 사용량을 최적화 할 수 있다. @Transactional(readOnly = true) 트랜잭션에 readOnly=true 옵션을 주면 스프핑 프레임워크가 하이버네이트 세션 플러시 모드를 MANUAL로 설정한다. 이렇게 하면 강제로 플러시를 호출하지 않는 한 플러시가 일어나지 않는다. 따라서 트랜잭션을 커밋하더라도 영속성 컨텍스트가 플러시 되지 않아서 엔티티의 등록, 수정, 삭제가 동적하지 않고, 또한.. 2022. 12. 2.
JPA Diarect(방언) 지정 1. 문제상황 JPA Dialect(방언)을 지정하라는 멘토님 피드백을 받았다. 2. 문제 원인 mysql dialect(방언) 를 지정해주지 않았다. 그렇다면 mysql dialect는 무엇인가? 세상엔 많은 데이터베이스 제품이 존재하고, 각각의 제품은 표준 SQL(ANSI SQL)을 제회한 독자적인 기능을 위한 SQL도 존해단다. 그리고 각각의 데이터베이스에서 제공하는 문법과 함수가 차이가 있다. ● 가변문자: VARCHAR(MySQL), VARCHAR2(Oracle), NVARCHAR(SQL SERVER) ● 문자열 자르는 함수: SUBSTRING(표준 SQL), SUBSTR(Oracle) ● 페이징: LIMIT(MySQL), ROWNUM(Oracle) 이러한 차이를 방언(Dialect)라고 하며,.. 2022. 11. 30.
실전 프로젝트 피드백 N+1 문제 1. 문제상황 - 기술 매니저님 피드백 개선 사항 중에 N+1문제가 발생하는지 체크해보라고 하셨다. - 후기 개수를 count 해주는 쿼리가 질행되는데 company(업체), theme(테마) 전부를 조회하고있는 부분을 확인했다. 2. 문제 원인 @OneToMany로 themeList를 불러오는 부분의 fetch type이 EAGER(즉시로딩)이어서 발생한 문제인것을 확인했다. 3. 문제 해결 fetch = LAZY(지연로딩) 로 수정 - 즉시로딩(EAGER)은 예측이 어렵고, 어떤 SQL이 실행될지 추적하기 어렵다. 특히 JPQL을 실행할 때 N+1 문제가 자주 발생한다. //JPQL select o From order o; -> SQL select * from order n(100) + 1 (orde.. 2022. 11. 29.
Unsupported Media Type, status 415 @RequestPart로 데이터를 입력할때 json형식으로 보내는 데이터 타입은 CONTENT Type에서 applicationJson으로 바꿔줘야한다. 2022. 11. 14.
java.lang.StackOverflowError: null 스프링으로 실전 프로젝트를 개발하던 중 해당 오류가 나왔다. 해당 오류는 JAVA에 Json 타입 변환 과정 중 일어난 오류이다. 이는 테이블과 테이블이 연관 관계에 있으며 이를 mode.addAttribute 메소드를 통해 데이터를 Front로 보낼때 Json으로 변환 과정중에 무한으로 참조가 순환되어 일어나는 오류로 간단히 해결할 수 있다. 문제 @Entity @Getter @AllArgsConstructor @NoArgsConstructor @Builder public class Theme { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) // @Column(name = "theme_id") public Long id; @JsonIgnore @M.. 2022. 11. 12.