스프링 데이터 JPA 분석

4662 단어 JPASpringJPA

구현체 분석

@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository<T, ID> ... {
	
    @Transactional
    public <S extend T> S save(S entity) {
    	if (entityInformation.isNew(entity)) {
        	em.persist(entity);
            return entity;
        } else {
        	return em.merge(entity);
        }
    }
}

대충 스프링 데이터 JPA 구조는
전체적으로 @Transactional(readOnly = true)를 이용해 읽기 전용으로 설정한 뒤에,
저장을하는 메서드가 나오면 메서드에 @Transactional을 넣어 우선순위를 주는 구조로 짜여있음.

참고로 트랜잭션 옵션에 readOnly = true 설정을 하면 트랜잭션 끝날때 flush를 생략하여 약간의 성능 향상을 얻을 수 있음

save() 메서드

  • 새로운 엔티티면 저장(persist)
  • 새로운 엔티티가 아니면 병함(merge)

이전 강의 내용을 떠올려 보면,
머지를 사용할때 업데이트가 아니고 덮어씌우기이므로,
비어있는 부분을 다 새롭게 덮어버린다.

취약한 단점은 DB 설렉터를 호출하여 데이터를 가져온다는 점이다.
머지를 데이터 업데이트 용으로 사용하는 것은 좋지 않은 방법.

새로운 에티티를 구별하는 방법

새로운 엔티티를 판단하는 기준

  • 식별자가 객체일 때 null로 판단
  • 식별자가 자바 기본 타입일때 0으로 판단
  • Persistable 인터페이스를 구현해서 판단 로직 변경 가능

이 경우에 Item 객체에서 idnull이면 새 엔티티,
값이 있으면 이미 있는 엔티티로 구분한다.

하지만, 이 아이디를 다른 형태로 값을 넣어서 받도록 구조를 짠다면,
비효율적인 로직이 발생되는데,

만약에 이상한 아이디 값을 넣어버린 상태로 save()를 하게 되면,
null이 아니므로 머지를 하게 된다.
그러면 select문을 통해 DB에서 값을 찾게 되지만, 해당하는 아이디는 없으므로 그 후에 새롭게 저장하게 된다.

물론 평소에는 @GenerateValue를 이용해
자동으로 할당해주는 방식을 많이 사용하기 때문에
상관없지만, 나중에는 @Id만 이용해서 직접 할당으로 방식을 바꾼다던지,
임시로 값을 설정해야하는 상황이 있을때가 있다.

그럴때 위와 같은 상황을 피하고 좋은 로직을 만들기 위해서는
판단 기준을 내가 설정해야한다.

Persistable<String>

  • 동작하려면 @EntityListeners(AuditingEntityListener.calss)를 추가해야한다.
  • isNew()를 구현해야한다.
  • 구현하면, 새로운 엔티티 판단기준을 이 메서드로 잡게 된다.

그럼 이 부분에서 createdDate를 판단 기준으로 바꾸기 때문에,
persist()로 진행하는 것을 확인할 수 있다.

좋은 웹페이지 즐겨찾기