JPA

    컬렉션 fetch join 및 페이징 applying in memory 오류

    이번에 프로젝트를 하는 도중에 2023-08-01 23:49:22.440 WARN 2334 --- [nio-8080-exec-7] o.h.h.internal.ast.QueryTranslatorImpl : HHH000104: firstResult/maxResults specified with collection fetch; applying in memory! 2023-08-01 23:49:22.441 DEBUG 2334 --- [nio-8080-exec-7] org.hibernate.SQL 이런 경고로그가 발생했다 어 뭐지 ..? 코드를 다시보니 JPAQuery contentQuery = selectFrom(board) .leftJoin(board.comments, comment).fetchJoin() ...

    JPA에서 Entity에 protected 생성자를 만드는 이유.

    엔티티에서 setter를 쓰는 것보다 생성자를 통해 파라미터를 넘기는 게 좋다. Setter를 무분별하게 남용하다 보면 여기저기서 객체(엔티티)의 값을 변경할 수 있으므로 객체의 일관성을 보장할 수 없기 때문. 그리고 setter는 그 의도를 알기 힘들기에 setter 사용을 자제해야한다. 그러므로 protect 생성자를 생성해서 아무데나 생성되는 걸 막는 게 좋다. (다른 사람이 쓰지 못하도록 제약한다.) 예시) Member member = new member (); member .setname("민우"); member .setname("하진"); 그러나 JPA 표준 스펙에 디폴트 생성자가 있어야하기에 private 생성자를 사용할 수 없다. 왜냐하면 jpa가 프록시 기술을 쓰는데 거기서 프록시 기술을..

    Entity를 Dto로 쉽게 변환 및 Entity노출을 최대한 자제해라.

    1. 엔티티 내부 구현을 캡슐화할 수 있다. 엔티티가 getter와 setter를 가지고 있다면 충분히 데이터 전달 역할도 할 수 있지 않을까? 여기서 엔티티란 도메인의 핵심 로직과 속성을 가지고 있고, 실제 DB의 테이블과 매칭되는 클래스이다. 그렇기 때문에 엔티티가 getter와 setter를 갖게 된다면, controller와 같은 비즈니스 로직과 크게 상관없는 곳에서 자원의 속성이 실수로라도 변경될 수 있다. 또한 엔티티를 UI계층에 노출하는 것은 테이블 설계를 화면에 공개하는 것이나 다름없기 때문에 보안상으로도 바람직하지 못한 구조가 된다. 따라서 엔티티의 내부 구현을 캡슐화하고 UI계층에 노출시키지 않아야하는 것은 충분히 데이터 전달 역할로 DTO를 사용해야 할 이유로 볼 수 있다. 2. 화면..

    qlrm 라이브러리와 mariaDB 사용시 주의사항

    Subscribe.Service @Transactional(readOnly = true) public List subscribeList(long principalId, long pageUserId) { StringBuffer sb = new StringBuffer(); sb.append("select u.id userId, u.username, u.profileImageUrl, "); sb.append("if( (select true from subscribe where fromUserId = ? and toUserId = u.id), true, false) subscribeState, "); // principalDetails.user.id sb.append("if(u.id = ?, true, fals..