๐ํ๊ฒฝ
IntelliJ Ultimate
Java 17
Spring boot 3.2.3
Gradle - Groovy
Dependencies:
Spring Web
Thymeleaf
Spring Data JPA
lombok
MariaDB 10.11
Spring Dev tool
๐๋ฌธ์
`Reply`๋ฅผ ์ญ์ ์ฒ๋ฆฌํ๊ธฐ ์ํ์ฌ /URI/{rno}์ `DELETE` ๋ฐฉ์์ผ๋ก ์ญ์ ๋ฅผ ์์ฒญํจ.
`Reply`์ ์์ด๋์ธ `rno`๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์กด์ฌํ๋ ์์ด๋๋ก ์ค์ ํ ๊ฒฝ์ฐ ์ ์์ ์ผ๋ก ๋์. ๊ทธ๋ฌ๋ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์๋ ๋ฒํธ๋ก ์ค์ ํ๊ณ ์์ฒญํ๋ฉด Exception ์์ด code 200์ ๋ฐํ ๋ฐ์์.
๊ธฐ๋ํ๋ Exception : `EmptyResultDataAccessException` 500
๊ฒฐ๊ณผ: 200
Hibernate:
select
r1_0.rno,
r1_0.board_bno,
r1_0.moddate,
r1_0.regdate,
r1_0.reply_text,
r1_0.replyer
from
reply r1_0
where
r1_0.rno=?
console์์ select๋ฌธ๋ง ์คํ๋๊ณ ์๋ฌด๋ฐ ์ค๋ฅ ์์ด ๋๋๋ ๊ฒ์ ํ์ธํ๋ค. ์ฌ์ง์ด `NoSuchElementException`๋ ๋ฐ์ํ์ง ์๋๋ค... ๊ทธ๋์ `deleteById()` ๋ฉ์๋๋ฅผ ๊น๋ณด๊ธฐ๋ก ํ๋ค.
`CrudRepository`์ ๊ตฌํ์ฒด์ธ `SimpleJpaRepository`์ `deleteById()` ๋ฉ์๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
@Transactional
@Override
public void deleteById(ID id) {
Assert.notNull(id, ID_MUST_NOT_BE_NULL);
findById(id).ifPresent(this::delete);
}
๋ด๋ถ์์ `findById()`๋ฅผ ์คํํ ํ ์กด์ฌํ๋ฉด `delete`๋ฅผ ์คํํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค. ๊ทธ๋ฐ๋ฐ `findById(id)`๊ฐ null์ผ ๊ฒฝ์ฐ ์๋ฌด๋ฐ Exception์ ๋ฐ์์ํค์ง ์๋๋ค!
2023๋ 1์์ ์์ฑ๋ ๋ธ๋ก๊ทธ์์ ๋ดค๋ `deleteById`์ ๋ฌ๋ผ๋ณด์๋ค. ์ถ์ฒ: https://velog.io/@baekgom/deleteById-delete
์ด๋ฏธ์ง ๋ด์์๋ `findById` ์คํ ์ `orElseThrow( () -> new EmptyResultDataAccessException)`๋ฅผ ๋ฐ์์ํค๊ณ ์์ผ๋ ์ง์ ๊น๋ณธ `SimpleJpaRepository`์๋ ํด๋น ๋ด์ฉ์ด ์์๋ค.
๊ทธ๋ผ ์ด์ `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) entityManager.find(type, entityInformation.getId(entity));
// if the entity to be deleted doesn't exist, delete is a NOOP
if (existing == null) {
return;
}
entityManager.remove(entityManager.contains(entity) ? entity : entityManager.merge(entity));
}
๋ด๋ถ์์ `entityManager`๊ฐ `find()`๋ก ๊ฐ์ ์ฐพ์ ๋ค ์กด์ฌํ ๊ฒฝ์ฐ `remove()`๋ฅผ ํธ์ถํ์ฌ ์ญ์ ํ๊ณ ์๋ค. ์ด ๋ถ๋ถ์ ์์ ๋ธ๋ก๊ทธ์์ ํ์ธํ `delete()` ๋ฉ์๋์ ๋์ผํ๋ค.
๋ณ๊ฒฝ๋ ์ด์ ๋ ์ ์ ์์ผ๋ `deleteById()`์ ๋ฌธ์ ๋ก ๋ณด๊ณ ์ญ์ ๋ก์ง์ ๋ณ๊ฒฝํ๊ธฐ๋ก ํ๋ค.
๐ํด๊ฒฐ
`Service`์์ ์ญ์ ๋ฉ์๋ ๊ตฌํ ์ `deleteById()`๋ฅผ ์ฌ์ฉํจ์ ๋ฐ๋ผ ๋ฐ์ํ๋ ๋ฌธ์ ๋ก ๋ณด๊ณ `findById()`๋ก ๊ฐ์ฒด๋ฅผ ์ฐพ์ ํด๋น ๊ฐ์ฒด๋ฅผ ๋งค๊ฐ๋ณ์๋ก `delete()`๋ฅผ ํธ์ถํ๊ธฐ๋ก ํ๋ค.
@Override
public void remove(Long rno) {
// replyRepository.deleteById(rno);
Optional<Reply> result = replyRepository.findById(rno);
Reply reply = result.orElseThrow();
replyRepository.delete(reply);
}
`NoSuchElementException`์ด ์ ์์ ์ผ๋ก ๋์ํ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๐์ฐธ๊ณ
์๋ฐ ์น ๊ฐ๋ฐ ์ํฌ๋ถ
https://velog.io/@baekgom/deleteById-delete
deleteById, delete
deleteById, delete
velog.io
https://docs.spring.io/spring-data/jpa/reference/repositories/core-domain-events.html#page-title
Publishing Events from Aggregate Roots :: Spring Data JPA
Entities managed by repositories are aggregate roots. In a Domain-Driven Design application, these aggregate roots usually publish domain events. Spring Data provides an annotation called @DomainEvents that you can use on a method of your aggregate root to
docs.spring.io