-
JPA @OneToOne 매핑이 안된다고? UniqueJpa 2020. 11. 4. 09:24
JPA @OneToOne 매핑이 안된다고?
Introduction
JPA를 사용하면서 @OneToOne 어노테이션을 많이 보고 사용했을 것이다. 이 글에서는 OneToOne 어노테이션을 사용했는데도, 데이터가 한개가 아닌 2개가 들어가서 @OneToMany로 들어가는 일이 있거나, 그런 궁금증을 가지신 분들이 보면 도움이 될 수 있다고 생각한다.
* 이 글은 JPA,, Database 사전지식이 있다는 가정하에 서술하였습니다.
* 환경(Intelli j, h2 database)
Situation
1. 두개의 1대1 양방향 관계의 엔티티가 있습니다. (Son, Parent)
@Entity @Table public class Son { @Id @Column private String name; @Column Integer age; @JoinColumn @OneToOne private Parent parent; }
2. 각자의 엔티티를 사용해서, Son 객체 2개를 생성해서 똑같은 부모 Foreign키를 사용해보겠습니다.
@Entity @Table public class Parent { @Id @Column private String name; @Column private Integer age; @OneToOne(mappedBy = "parent") @JoinColumn private Son son; }
3. 구동결과
```java
public class FamilyService {public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello"); EntityManager em = emf.createEntityManager(); EntityTransaction tx = em.getTransaction(); tx.begin(); Parent parent = new Parent(); parent.setName("엄마"); Son son1 = new Son(); Son son2 = new Son(); son1.setName("아들1"); son1.setAge(11); son1.setParent(parent); parent.setSon(son1); son2.setName("아들2"); son2.setAge(10); son2.setParent(parent); em.persist(parent); em.persist(son1); em.persist(son2); tx.commit(); em.close(); emf.close();
}
}
- 이상하게 너무 잘돌아간다. (아들1과 아들2는 알고보니 형제였던거임)
Hibernate 를 보면 OneToOne 을 비웃기라도 한듯이 너무 잘들어 간다.
사실 정상적인 구동 결과이다. DB자체에다가, 물리적으로 제약을 걸어준 것도 아니고, 자바입장에서도 객체 레퍼런스값을 집어넣는데 문제가 생길 이유도 명분도 없다.
근데 이왕 어노테이션 까지 붙였으면 Hibernate 가 영속성 컨텍스트나 1차캐시 안에서 무언가 해줄거라고 생각했던 내 착각이었다.
결론적으로 ORM에서 말하는 1:1 , 1:N 관계라는 것은 관계형 데이터베이스 기준의 관계이다.
특히 1:1 같은 경우에는 필요에 따라 적절하게 제약조건을 걸어줘야 한다.
- DB 에다가 물리적으로 걸어줘야하나?
(그냥 디비에다가 걸어주면 되고)
- 아니면 Hibernate 에서 해결할 방법이 있을까?
보면 알듯이 조인컬럼에다가 unique 제약 조건이 걸 수 있는데, 친절한건지 unique가 false가 되어있다.
이걸 True로 바꿔주고 다시 기동해보면
객체에 참조값 다 들어가고 persist 하기전 트렌젝션 커밋에서 바로 unique 제약조건 걸려서 오류가 뜬다.
Service에 Exception을 해야했는데 귀찮아서 안했지만 아마 Exception 띄우고 진행하면 rollback 이 될거다.
'Jpa' 카테고리의 다른 글
JPA 장인께서 소개하는 MySQL 사용시 JPA 성능 향상 방법 9가지-번역 (0) 2020.10.28