JPA

[JPA] deleteById(), delete()

da77777 2022. 7. 27. 07:42

 

실패 테스트를 하기 위해 존재하지 않은 userId를 넣고 아래의 코드를 실행하니

EmptyResultDataAccessException이 발생했다.

userRepository.deleteById(userId);
No class com.lezhin.coding.domain.User entity with id 0 exists!
org.springframework.dao.EmptyResultDataAccessException: No class com.lezhin.coding.domain.User entity with id 0 exists!
	at org.springframework.data.jpa.repository.support.SimpleJpaRepository.lambda$deleteById$0(SimpleJpaRepository.java:176)
	at java.base/java.util.Optional.orElseThrow(Optional.java:408)
    ...

에러 뜨길 바라며 돌린 거긴 했는데 처음 보는 에러라서 신기했다. 

 

검색 결과가 0일 때 발생하는 에러라고 한다.

delete를 했는데 뭔 검색이야 하고 콘솔 봤는데 내 눈에 들어오는 선명한 select문

deleteById()열어보고 싶어진다 SimpleJpaRepository.java로 가자

	@Transactional
	@Override
	public void deleteById(ID id) {

		Assert.notNull(id, ID_MUST_NOT_BE_NULL);

		delete(findById(id).orElseThrow(() -> new EmptyResultDataAccessException(
				String.format("No %s entity with id %s exists!", entityInformation.getJavaType(), id), 1)));
	}

findById로 찾고 delete() 메서드를 사용한다.

 

 

그럼 delete()는 뭔데

	@Override
	@Transactional
	@SuppressWarnings("unchecked")
	public void delete(T entity) {

		Assert.notNull(entity, "Entity must not be null!");

		if (entityInformation.isNew(entity)) {
			return;
		}

		Class<?> type = ProxyUtils.getUserClass(entity);

		T existing = (T) em.find(type, entityInformation.getId(entity));

		// if the entity to be deleted doesn't exist, delete is a NOOP
		if (existing == null) {
			return;
		}

		em.remove(em.contains(entity) ? entity : em.merge(entity));
	}

 

 

 

차이가 무엇인고

  • deleteById()는 findById()와 delete()를 내부적으로 호출하고, EmptyResultDataAccessException 던지는데 형식이 정해져 있다.
  • delete()는 entity가 null인지 체크하고 null이면 InvalidDataAccessApiUsageException 를 던지는데, 사용자가 메세지를 설정할 수 있다.

 

EmptyResultDataAccessException는 많은 사람들이 null을 return해주는 방식으로 처리해주더라. 근데 나는  void 라서 return할 내용이 없었고, 예외처리하자고 필요없는 return을 만들고싶진 않았다. 

 

delete()를 사용하려면 보통 findById()를 같이 사용하게 될텐데, findById()나 delete()나 던지는 예외를 내 취향대로 처리할 수 있으니... 이 방법이 더 편하지 않을까

 

그래서 나는 후자로 처리할 예정