Database 와 Object 간에는 기본적인 패러다임 차이가 존재한다. Database 관점 슈퍼타입 - 서브타입의 논리 모델이 존재한다. 이를 물리 모델로 구현할 수 있는 여러 전략이 존재한다. Joined Table 전략 Single table 전략 Table per class 전략 1. Joined Table 전략 슈퍼타입 테이블을 만들고 각각의 모든 서브타입 테이블을 별도로 생성하는 구조. Item 슈퍼타입 테이블에 별도의 `data_type` 컬럼을 두어 해당 테이블에서 어느 서브타입 테이블을 가리키는지 구분한다. 가장 정규화된 방식으로 저장 공간이 효율화됨. 정석적인 방법으로 JOIN 으로 인해 성능 저하 위험 존재한다고는 하나, 미미함. (JOIN을 잘쓴다면) 부모 - 서브타입 테이블에 ..
JVM/JPA
요구사항 가정 회원당 무조건 하나의 락커 를 점유한다. 락커 또한 무조건 한명의 회원만 사용할 수 있다. 테이블 설계 1:1 관계가 성립해야한다. 그러나 부모 자식 관계가 성립해야하고 외래키는 존재해야한다. JPA Entity class 설계 단 1:1로 살아있는 테이블을 만든다고 하면 1:1 연관관계 설정 (@OneToOne) 필요하다. 주 대상 테이블 || 대상 테이블에 외래키와 UNIQUE 제약조건을 건다. (그래야 1:1이 제대로 성립한다.) FK를 회원에 둘 것인가 사물함에 둘 것인가? 나라면 이렇게 설계하겠다. 회원에 사물함 아이디를 FK로 보유한다. 엔티티 클래스에서는 연관관계 주인으로 삼는다. 테이블 설계상으로나 비즈니스 로직상으로나 사물함으로부터 회원을 조회하기보다 특정 회원의 사물함을 ..
기본키 생성 전략에 따른 JPA 의 기본 동작 차이. IDENTITY IDENTITY 전략에서는 PK (auto_increment) 값이 Insert 쿼리가 DB에 COMMIT 되는 시점에 확정된다. 문제 상황 영속성 컨텍스트를 가진 JPA 입장에서 어떤 트랜잭션 내에서 COMMIT 하기 전에 PK (ID) 를 사용해야 한다면 어떻게 해야할까? em.persist(entity) 시점에 INSERT 쿼리를 실행한다. (아직 COMMIT 전) Member.java @Entity @Table(name = "member") @NoArgsConstructor(access = AccessLevel.PROTECTED) @Getter public class Member { @Id @GeneratedValue(strat..
객체 - DB 간 패러다임 불일치 객체는 참조 (Reference) 로, DB는 외래키(foreign key) 로 연관관계를 맺는다. 이 때문에 OOP 와 DB 간의 패러다임 불일치가 발생한다. 1. 객체지향 언어는 참조로, RDB 는 외래키로 맵핑한다. Team 이 부모, Member 가 자식 테이블이라 해보자. MemberTeam.java member_team.sql 참조가 아닌 Foreign Key (teamId) 로 맵핑한다. -- 팀별로 소속된 멤버를 모두 불러옴 SELECT * FROM Member AS m JOIN Team AS t -- teamId 와 team.id 를 매핑 ON m.teamId = team.id 2. Entity 신뢰 문제 DB Entity - Class 간 매핑시 최초에..
🎯 Goals Entity 는 사실상 Getter Setter 및 핵심 비즈니스 메소드만 있어야한다. 화면 디자인과 관련된 로직을 추가해선 안된다. API 설계시 entity 객체를 반환하지 않아야한다. 라는 위 두 명제를 이해한다. 잘못된 예제 Member.java @Entity @Getter @Setter public class Member { @Id @GeneratedValue @Column(name = "member_id") private Long id; private String userName; @Embedded private Address address; // 연관 관계의 주인이 아닌 경우 읽기 전용이 됨. // `member` field in order 에 의해 매핑되었다는 것을 명시. @..