궁금한점1

김파란·2024년 6월 13일

project

목록 보기
2/9

1. 연관관계 매핑시 SET 대신 LIST를 쓰는 이유

1). List가 더 나은 이유 1

2). List가 더 나은 이유 2

  • hibernate문서를 보면 연관 관계를 맺을 땐, List가 더 나은 성능을 보인다 했다.
  • List를 사용하는 것이, hibernate 입장에서나, 개발 환경에서나 유리하다.
  • Set을 사용한 경우, 이걸 선택한 이유가 있는지, 옛날 코드인지 확인할 필요가 있다.
    참고 https://brorica.tistory.com/127

3). Set이 더 나은 이유 1

4). Set이 더 나은 이유 2

5). 결과

  • Lazy 상황일때는 Set보다 List가 더 성능이 좋다
  • 다만 ManyToMany일때는 Set이 더 좋을 수도 있다

2. fetch join과 on

1). 컬렉션조회시 fetch join과 on절을 함께 쓰면 오류가 난다

  • fetch join시 컬렉션이 모두 조회가 되어야 하는데 on절을 쓰면 전부 조회가 되지 않기 때문에 실행 불가능
  • fetchJoin으로 join 대상 테이블까지 한번에 가져오고 영속성 컨텍스트에 반영한다. 그래서 임의로 데이터를 빼고 조회하면 DB에는 해당하는 데이터가 없다고 판단
  • 엔티티값을 변경하면 DB에 쉽게 반영되는 걸 알 수 있듯이 최악의 경우 DB에서 삭제될수도 있다
  • fetch join 결과는 모든 엔티티가 있을 것이라 가정하고 사용해야 한다. 필터링을 걸어버리면 객체 상태와 DB상태 일관성이 깨짐
    -> 왜냐 더티체킹으로 엔티티 값을 변경하면 DB에 반영이 되어버린다.
Team team = new Team();
        team.setName("teamA");
        em.persist(team);

        Member member1 = new Member();
        member1.setUsername("m1");
        member1.setTeam(team);
        em.persist(member1);

        Member member2 = new Member();
        member2.setUsername("m2");
        member2.setTeam(team);
        em.persist(member2);

        em.flush();
        em.clear();

        List<Team> result = em.createQuery("select t from Team t join fetch t.members m where m.username = 'm1'", Team.class)
                .getResultList();

        for (Team team1 : result) {
            System.out.println("team1 = " + team1.getName());
            List<Member> members = team1.getMembers();
            for (Member member : members) {
                System.out.println("member = " + member.getUsername());
            }
        }
        List<Team> resultList = em.createQuery("select t from Team t join fetch t.members", Team.class)
                .getResultList();
        for (Team team1 : resultList) {
            System.out.println("team1 = " + team1);
            List<Member> members = team1.getMembers();
            for (Member member : members) {
                System.out.println("member = " + member);
            }
        }

    }
// 결과
// 데이터가 사라져버림
team1 = teamA
member = m1
Hibernate: select t1_0.id,m1_0.team_id,m1_0.id,m1_0.username,t1_0.name from team t1_0 join member m1_0 on t1_0.id=m1_0.team_id
team1 = Team(id=1, name=teamA)
member = Member(id=1, username=m1)

2). 가능한 경우

  • 일관성에 문제가 없으면 사용해도 된다
    Select m from Member m join fetch m.team t where t.name=:teamName
    이것처럼 멤버 -> 팀을 조회하는데 팀이름을 조회한다 (다대일)은 가능
  • 하지만 left join fetch로 변경하면 일관성이 깨질 수 있다
    -> team이 없는 멤버들도 추가로 끌고오기 때문
  • 일관성이 깨지더라도 조회용으로만 사용하면 상관없지만 꼭 조회용으로만 사용해야 한다 변경X
    참고
  1. https://tecoble.techcourse.co.kr/post/2023-11-01-jpa-fetch-join/
  2. https://www.inflearn.com/questions/15876/fetch-join-%EC%8B%9C-%EB%B3%84%EC%B9%AD%EA%B4%80%EB%A0%A8-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4
    https://elsboo.tistory.com/34

3). 결론

  • 결론: fetch join의 대상은 on, where 등에서 필터링 조건으로 사용하며 안된다
    -> 사용하고 싶으면 엔티티가 아닌 값으로 조회하면 된다(DTO)

3. @Aspect

  • @bean으로 Aspect를 등록하려고 하면 순환참조가 일어난다
  • @Around로 전부다 했을 경우 생겨나는 일인데, 이럴때는 Config클래스를 빼버리면 된다
  • 아니면 @Component도 방법인데, 순환참조가 일어날 수 있다 주의

4. Embedable

  • Null값을 허용하지 않음 -> 오류가 뜬다

5. Jwt Header

  • 웹상에서 header에 jwt를 넣고 redirect를 하는건 쉽지않다
  • 다른 웹이라도 타는건지 (잘모름) 클라이언트 웹의 Header에 jwt가 넣어지는게 아니라 다른 웹에 넣어지고 redirect된 사이트에는 넣어지지 않기때문에 작동을 안함
  • cookie에 넣고 하는게 좋다

6. Security

  • Jwt는 다른 필터를 가져다 쓰기 때문에 processing url이나 entrypoint url을 수정하기 쉽지 않다
  • 기존 그대로 쓰거나 AuthenticationEntryPoint 상속받아서 URL을 바꾸거나
  • processing url은 form Login처럼 자유자재로 URL을 바꿀수는 없어 보인다

7. Git

  • gitignore에 넣어도 계속 추적되는 상황이 발생하는건 캐시때문에 그런거다
git rm -r --cached .
git add .
git commit -m "fixed untracked files"
git push
  • 이렇게 캐시를 없애고 다시 push를 해주면 정상작동하는걸 볼 수 있다

0개의 댓글