이러한 설계과정은 ERD(Entity Relation Diagram)을 통해서 확인하고 구성해야된다.
JPA를 이용할 경우 반드시 "방향성"에 대한 설정이 필요하다!
SpringBoot 2.0 이상의 findOne()
스프링부트 2.0 에서 findOne 메소드는 findById()로 변경되었다. 또한 return 타입은 Optional 인데 Optional 타입은 null을 대신한다고 생각하는게 좋다. Optional의 말은 그대로 존재할 수 있고 존재하지 않을 수 도 있다는 의미이다. 과거 코드에서는 일일이 Null을 체크했지만 optional 부터는 null에 대해 신경쓰지 않아도 된다.
Optional을 쓸때는 주로 get() 이나 ifPresent()를 사용하여 결과를 반환받거나 처리하게 된다.
spring.jpa.database-platform을 지정해야 되는 이유!
이거에 대해 지정하지 않으면 MyISAM으로 지정되는데 이는 데이터 무결성을 제대로 체크하지 않는다. 또한 Auto로 지정되어있기 때문에 Mysql을 사용할 때 아래와 같이 지정하자.
@Id의 GenerationType.AUTO 와 GenerationType.IDENTITY
GenerationType.AUTO 타입을 사용하면 DB에 hibernate_sequence라는 테이블이 생기게 되어 이 번호를 유지하는 방식으로 진행된다. 이렇게 되면 IDENTITY 타입으로 변경하더라도 auto_increment로 처리되지 않기때문에 테이블을 삭제후 새로 만들어주어야 한다.
따라서 IDENTITY 타입을 쓸때는 hibernate_sequence 에 대해 확인하고 사용하자.
JPA join 처리
@Query에서 사용하는 JPQL 자체가 테이블을 보는 것이 아니라, 클래스를 보고 작성하기 때문에 hibernate 5.0.X 경우 참조관계가 없는 다른 엔티티를 사용하는 것이 불가능하다. 하지만 SpringBoot 2.0이상에선 hibernate 5.2.X에서는 참조관계가 없어도 'ON'을 이용해서 Left OUTER JOIN을 처리할 수 있다.
SpringBoot 2.0 이상일 때,
Member.java
~~~ @Getter @Setter @Entity @ToString @Table(name="tbl_members") @EqualsAndHashCode(of="uid") public class Member {
@Getter @Setter @ToString(exclude = "member") @Entity @Table(name="tbl_profile") @EqualsAndHashCode(of="fname") public class profile {
}
@Query("Select m.uid, count(p) from Member m LEFT OUTER JOIN profile p "+" ON m.uid = p.member where m.uid = ?1 GROUP BY m") public List getMemberWithProfileCount(String uid);
@Test public void testFetchJoin1() { List result = memberRepo.getMemberWithProfileCount("user1");
@OneToMany private Profile profile;
@OneToMany(cascade = CascadeType.ALL) @JoinColumn(name="pdsno") private List files;
Rolled Back transaction for ...
~~~ 롤백처리가 되었기 때문이다. 이러한 롤백처리를 막기위해 위에 @Commit을 필요로한다.
- SpringBoot 2.0 이하일 때,
두 객체 클래스간에 서로의 객체를 만들고 참조를 해주어야 한다.
즉, Member.java 에 profile class에 대한 참조가 필요하다는 점이다. 아래 코드 참조
## Cascading 필요성
영속성 전이를 통해서 연관관계가 있는 정보를 같이 삭제하게 하기 위함이다.
예를 들어, 유저가 회원가입해서 출석부에 출석을 했다. 해당 유저가 만약 회원탈퇴를 한다면 출석부에 역시 유저가 사라져야 된다. 그렇기에 유저의 정보를 지우기 위해서 영속성 전이에 대해 처리가 필요하다.
## @Modifying , @Transaction
@Modifying의 경우 기본 @Query에서는 Select 만 지원을 한다 그렇기 때문에 @Modyfying이 Insert,Update,Delete 작업을 처리하게 지원을 해준다.
이와같은 Update나 Delete 작업을 하기위해서는 코드에는 @Transaction로 트렌젝션 처리가 필요하다. 하지만 처리되지 않을경우가 있는데 이는