ORM란
객체를 데이터베이스 테이블에 매핑해준다는 것입니다.
패러다임 불일치를 해결하기 위해 개발자들이 기본적으로 해야했던 일들을 대신처리해주어 개발 생산성이 향상됩니다.
JPA란?
ORM의 자바 표준 인터페이스 입니다.
엔티티의 상태(생명주기)에 대해서 설명해주세요
기본적으로 비영속상태로 아무관계가 없다가
퍼시스트되면 영속상태가 됩니다. 여기서 트랜잭션으로 커밋되면 DB에 가게 됩니다.
또는 리무브 당하면 영속상태가 해제됩니다.
또는 준영속 상태라고 있는데, 트랜잭셔널 블록을 벗어나는 경우에 그렇게 됩니다. 또는 영속성 컨텍스트를 클리어하거나 삭제하면 그렇게 됩니다.
영속성 컨텍스트가 무엇인가?
엔티티를 1차캐시로 관리해주고, SQL쓰기 저장소가 있어서, 쓰기 지연을 지원하는 저장소입니다.
영속성 컨텍스트의 장점은 무엇인가?
- 1차캐시로 DB를 타는 횟수를 줄여줄 수 있습니다.
- 1차캐시로 엔티티의 동일성을 보장해줍니다.
- 퍼시스트한 엔티티를 트랜잭션이 끝날때, 한꺼번에 처리해주어, 성능이 오히려 향상될 수 있습니다.
- 페치.레이지에 대하여 지연 로딩을 지원합니다.
- 수정된 엔티티에 대하여 변경 감지 기능을 지원합니다.
jpa 동작과정을 설명해주세요(저장할때)
퍼시스트하면 1차캐시에 저장되면서 SQL 쓰기 저장소에 쿼리가 생성됩니다.
트랜잭션이 종료되고 DB에 인서트문을 실행할때, 한꺼번에 전송되고, 트랜잭션 커밋합니다.
jpa 동작과정을 설명해주세요(수정할때)
불러오기하면 엔티티의 스냅샷이 찍히고, 만약 수정한후, 트랜잭션을 종료하고 DB전송할떄
스냅샷과 현재 엔티티를 비교하여 변경 감지한후, 쿼리를 생성하여 한번에 전송합니다. 그 후 커밋합니다.
- ManyToOne 쓴 이유는? 반대쪽에서 OneToMany 쓸수도 있지 않나요?
OneToMany의 경우, 하나의 엔티티가 다른 많은 엔티티를 관리해야하는데.. fk의 경우 ...
(찾아보기)
(결국 연관관계의 주인이라는 것인데, 연관관계의 주인은 외래키 관계자입니다. 팀과 멤버라는 테이블이 있고 , 일대다라고 했을때. 팀에는 멤버에 관한 정보가 없지만, 멤버에는 팀에 대한 정보가 있으므로, 외래키를 관리합니다. 그래서 다에 해당하는 멤버가 관리자로 일대다가 아닌 다대일을 사용해야 합니다.
- Hibernate는 뭘까요?
JPA 구현체 중 하나로, 사실 하이버네이트가 먼저 생기긴 했습니다.
- Open Session In View
컨트롤러나 뷰단에서 데이터를 조회하고, 수정할 수 있게 하는 방법입니다. 그러니까 Controller딴에 Transactional을 붙이는 것과 유사하다고 할 수 있습니다.
하지만, 컨트롤러나 뷰단에서 데이터를 수정할 수 있으므로 DTO를 넘겨주는 방식이 더 나아 보입니다.
(책 찾아보기)
트랜잭션 범위에 대한 것인데, 뷰에서도 지연로딩을 사용할 수 있게 되는 장점이 있습니다.
- JPA 사용할때랑 직접 SQL 사용할때랑 어떤 차이?
SQL을 사용하면, 그러니까 jdbc를 사용한다는 말씀이시죠? 그 뜻은 ResultSet에서 값을 인서트하고, 불러오기 하는 과정을 한번 작성해두면 괜찮을 수도 있는데, 만약 entity를 수정하게 되면, 많은 부분을 수정해야합니다. 하지만 JPA를 사용하는 경우, Entity를 수정하면 알아서 수정해주기 때문에 , 이게 막 많은 코드를 수정하다보면 실수가 발생할 수 있는데, 그러니까 생산성이 향상됩니다.
- @transactional 동작 과정
- readOnly 붙인 이유
해당 Transactionl이 붙은 클래스는 모든 메소드에 transactionl이 작동한다는 뜻으로, method가 트랜잭셔널 하다는 것은, 만약 그 메서드가 실행됐을 때, 커넥션이 연결되지 않았으면, 커넥션을 맺고, 트랜잭션을 시작합니다. 그리고, 트랜잭셔널 부분이 끝나는 경우, 트랜잭션을 종료하면서 데이터베이스에 커밋합니다. 커넥션을 끊습니다.
ReadOnly를 붙이면, 값을 읽어온 후, 수정하지 않겠다는 뜻입니다. 수정하지 않는다면, 더이상 값을 읽어오지 않아도 되는 부분에서 커넥션을 끊어도 되겠죠. 그러한 성능의 이점이 있습니다.
- JPA FetchType
- LAZY와 EAGER 각각 어떤 기준으로 사용하시는지?
기본적으로 LAZY를 사용하는 것이 맞습니다. 그러나, 해당 값을 항상 엔티티와 사용하게 되는 경우, 최적화를 위해 EAGER를 사용합니다.
- N+1 문제
예를 들어 팀,과 멤버로, 일대다 관계인 상황을 생각해 봅시다. 이때 팀엔티티에서 멤버가 페치이거입니다. JPQL을 사용하여 팀을 불러오는 경우, 페치 이거이므로, 멤버도 같이 불러와야합니다. 처음에 해당 멤버가 영속성 컨텍스트에 있는지 찾습니다. 그후, 해당 멤버가 영속성 컨텍스트에 없으면 DB에서 불러옵니다. 그렇게 해서, 모든 멤버를 DB에서 불러오게 될 수도 있습니다. 이런 경우에 N+1 문제가 발생합니다. EAGer를 레이지로 바꾸거나, 배치사이즈를 설정하거나 하여 N+1문제를 막을 수 있습니다.
(레이지일떄 N+1 문제가 발생하는 경우?? 찾아보자)
- 엔티티 매핑을 할 때 ManyToOne을 lazy로 설정해주지 않았던 이유
해당 엔티티와 연결된 값이 하나만 있으므로, 값 하나정도는 페치 이거로 불러와도 된다는게 기본전략입니다.
- JPA 사용하면서 맞닥뜨린 문제 있는지?
다른 도메인에 있는 엔티티를 서로 다대다로 호출하려다가, 순환참조에 걸린 적이 있습니다. 결과적으로 해당 엔티티들을 같은 도메인으로 두게 되었습니다.
- 본인이 생각하기에 칼럼이 많고 적고의 기준은 어떻게 되는지?
20개 이상이면 컬럼이 많다고 생각합니다.
- JPA에서 PK는 어떻게 설정하는지?
Long으로 ID 애노테이션을 사용합니다. 그리고 PK전략이 오토 인크리먼트, 시퀀스, 테이블 전략이 있는데, 테스트 용으로는 오토인크리먼트를 사용할 것 같습니다. 하지만, 실제로 사용할때는 시퀀스나 테이블 전략을 사용할 것입니다.
https://doorisopen.github.io/developers-library/Interview/2020-06-25-interview-jpa
https://smjeon.dev/etc/interview-question/#jpa-질문
마지막으로 Transactional propagation
→ ORM JPA책에서도 잘 안나옴
Transactional 애노테이션과 propagation
테스트 메소드가 트랜잭션을 생성하지 않도록 하는 것도 있겠고
부모 트랜잭션이 존재하는 경우, 트랜잭션을 생성하지 않고, 부모 트랜잭션에 참여하는
부모 트랜잭션이 업슨 경우, 트랜잭션이 없는 것으로 사용하는
부모 트랜잭션과 상관없이 새 트랜잭션을 생성하는(부모 트랜잭션은 종료한다)
부모 트랜잭션과 상관없이 Non transaction하게 동작( 부모트랜잭션은 종료하곘죠)
'공부기록 > JPA' 카테고리의 다른 글
transaction isolation level (0) | 2021.12.29 |
---|---|
트랜잭션 격리 수준 (0) | 2021.12.20 |
IdClass vs EmbeddedId (0) | 2021.12.20 |
자바 ORM 표준 JPA 프로그래밍 #1~5 (0) | 2021.05.03 |