본문 바로가기

JPA19

서비스 계층에서 @Transactional 이 없는데 디비 저장이 가능했던 이유 강의를 보다가 문득 다음과 같은 코드를 발견했습니다. 보통 서비스 계층에서 @Transactional 을 통해서 감싸주는게 일반적이였습니다. Repository 도 역시 아무것도 없습니다. 어떻게 저 save 문이 잘 동작했던 것일까? 결론부터 이야기 하면 @Transactional이 없는데 디비저장이 된다는것이 아닙니다. 즉, @Transactional이 있습니다.. 어디에 있는지는 디버깅을 천천히 해보면서 따라가보겠습니다. 처음에 UserRepository에 어떤 구현체가 주입되는지 살펴보면 SimpleJpaRepository 를 주입받습니다. 그래서 SimpleJpaRepository 의 save를 살펴보면 네 존재합니다. 마찬가지로 @Repository 어노테이션도 SimpleJpaReposito.. 2022. 3. 29.
[JPA/WARN] firstResult/maxResult ... collection fetch : applying in memory! OneToMany 인 상황에서 fetch Join을 하여 가져오는 경우 페이징 할때 발생하는 경고다. 데이터베이스에서 페이징을 할수 없기 때문에 어쩔수 없이 메모리로 올려서 페이징을 해야하는 데 이때 메모리가 잘못하면 터질수 있으므로 경고를 날리는 것임. 일대다 페치조인의 위험은 포스팅에서 찾아보면 나와있다. 2020. 8. 8.
[JPA/ERROR] fetch join & DTO https://stackoverflow.com/questions/12459779/query-specified-join-fetching-but-the-owner-of-the-fetched-association-was-not query specified join fetching, but the owner of the fetched association was not present in the select list I'm selecting two id columns but get error specified: org.hibernate.QueryException: **query specified join fetching, but the owner of the fetched association was not p.. 2020. 8. 8.
[JPA] 페이징 API 와 일대다 페치조인 이전 포스팅 영상에서 일대다 테이블을 다시한번 살펴보자. 페이징 API를 통해 1번부터 2개 가져오라는 명령을 한다면 group1이 wonjun을 가지는 것을 누락하게 된다. 페이징 API를 쓸때는 테이블의 결과를 한번 곰곰히 생각해보는것도 좋을 것 같다. 참고) 페이징 명령어 setFirstResult() : 시작위치 setMaxResults() : 개수 2020. 8. 6.
[JPA] 벌크연산 주의점 더티 체크로 엔티티를 변경하기에는 엔티티가 너무 많은경우에 사용한다. 영속성 컨텍스트와 상관없이 바로 데이터베이스에 쿼리를 날리기 때문에 벌크연산하고 영속성 컨텍스트를 초기화 해주자. 다시말하면 데이터베이스의 데이터와 영속성 컨텍스트의 데이터가 차이가 날수도 있다는 뜻이다. 따라서 벌크연산을 시행한 후, clear()를 통해 영속성 컨텍스트를 비우는 것이 좋다. 명령어 : executeUpdate() 2020. 8. 6.
[JPA] 일대다 조인할때 영속성 컨텍스트 내부 모습 & distinct 엔티티와 데이터베이스를 매핑을 아래와 같이 한다. @Entity class User{ ... @ManyToOne(fetch = FetchType.LAZY ) private Team team; ... } @Entity class Team{ @OneToMany(mappedBy = "team") // 기본적으로 LAZY private List users = new ArrayList(); ... } 데이터 베이스는 미리 데이터를 인서트 해놓았다. 팀을 기준으로 유저들을 join 하면 재밌는 일이 발생한다. 즉 아래와 같은 코드가 있을때 출력을 생각해보자. List teams = em.createQuery("select t from Team t join fetch t.users").getResultList(); .. 2020. 8. 6.
[JPA / JPQL] 페치조인 & 지연로딩 지연로딩을 기본 페치전략으로 가져가는 경우 어떤 문제점이 있을까?? 예시로 바로 살펴보자. @Entity class User{ ... @ManyToOne(fetch = FetchType.LAZY ) private Team team; ... } @Entity class Team{ @OneToMany(mappedBy = "team") // 기본적으로 LAZY private List users = new ArrayList(); ... } 영속성 컨텍스트는 깨끗하게 비워져있는 상태라고 가정한다. 아래의 데이터베이스 상황에서 쿼리를 날린다면?? List users = em.createQuery("select u from User u",User.class).getResultList(); for (User u : u.. 2020. 8. 6.
[JPA / JPQL] @ManyToOne, @OneToOne 과 묵시적 조인 JPQL 은 엔티티를 대상으로 날리는 sql 과 비슷하다. JPQL에서 주의해야할 점이 있다. 만약 User 라는 객체에 Team이라는 객체가 @ManyToOne으로 매핑되었다고 가정하자. 유저마다 유저가 속한 팀을 가져오라는 쿼리는 다음과 같다. select u.team from User u ; 그러면 당연하게 받아 들일 수도 있다. 하지만 실제 sql 을 보면 JOIN문이 들어가 있다. 그럴수 밖에 없다. 유저의 팀을 가져오려면 유저와 팀을 조인해야한다. 이를 JPQL에서는 묵시적으로 조인해준다. 실제 날리는 쿼리는 아래와 같다. select t from User u join u.team t 이처럼 단일값을 연관관계로 가지는@ManyToOne 이나 @OneToOne 에서 "." 을 이용하여 가져온다면.. 2020. 8. 6.
[JPA] @Embeddable , @Embedded class User{ private int age; private int money; private String name; private String 초등학교; private String 중학교; private String 대학교; ... } User 가 가지고있는 속성이 너무 지저분하고 한눈에 알아보기 힘들다. 이때 초등학교,중학교,대학교 는 학교라는 공통적인 속성안에 포함되어 있는 것이므로 학교라는 클래스를 따로 만들어서 관리하면 되지 않을까? class User{ private int age; private int money; private String name; private 학교 학교정보; ... } 좀더 심플해졌다. 하지만 문제가 있는데 학교정보라는 값이 공유가능한지가 문제이다. 왜냐하면 기존.. 2020. 8. 6.