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
참고
- https://tecoble.techcourse.co.kr/post/2023-11-01-jpa-fetch-join/
- 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
- 웹상에서 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를 해주면 정상작동하는걸 볼 수 있다