데이터베이스에서 데이터를 삭제할 때는 논리 삭제와 물리 삭제가 있습니다.
항상 삭제 기능을 물리적으로 구현해왔으나, 이번에는 '최근에 삭제한 값 조회' 기능을 위해 사용자가 삭제한 데이터를 활용해야 했습니다.
그래서 이번 포스팅에서는 논리 삭제(Soft Delete)를 구현하고, 삭제된 데이터를 조회하기 위해 Hibernate
의 필터링을 활용했습니다.
데이터베이스의 테이블에서 물리적으로 삭제하지 않고, 삭제된 것으로 표시하는 업데이트 프로세스를 수행한다.
UPDATE table
SET is_deleted = 1
WHERE condition;
delete 쿼리를 사용해 테이블에서 영구적으로 제거하므로, 데이터가 완전히 삭제돼 복구가 불가능하다.
해당 포스팅의 실제 코드는 EunsilSon - BookMarky에서 확인할 수 있습니다.
💡 삭제된 데이터임을 표시하는 flag 용도로 별도의 컬럼을 추가 생성해야 합니다.
isDeleted
이름의 Boolean 타입 변수 추가isDeleted
의 값을 정해둔 값으로 초기화하기 위함💡 Soft Delete를 위해서는 delete 메소드가 실행될 때 DELETE
쿼리 대신 UPDATE
쿼리를 발생시켜야 합니다.
💡 위에서 봤던 Passage
엔티티 클래스에 아래 어노테이션들을 주입시킵니다.
데이터베이스를 보면 사용자가 삭제한 데이터는 실제 삭제되지 않았으며,
is_deleted
컬럼을 이용 삭제된 것은1
, 삭제 안 된 것은0
으로 구분합니다.
이를 해결하기 위한 2가지 방법이 있습니다.
1. JPQL을 작성해
@Where
설정 무시
- 삭제된 데이터를 조회하는 메소드를 따로 생성합니다.@Query(value = "Select * From table Where is_deleted = true", nativeQuery = true)
위 방법으로 간단하게 해결할 수 있지만, 해당 이슈에 대해 다른 방법이 있을 것 같아 Hibernate 공식 문서를 찾아보게 되었습니다.
2. Filter 적용
공식 문서의 Filter 설명란을 보면 "Soft Delete 된 데이터를 숨기는 필터" 라고 적혀있습니다.
이 내용을 반대로 하면, 필터를 이용해 Soft Delete 된 데이터를 꺼낼 수도 있습니다.
Hibernate 공식 문서의
8.1. Filters
부분을 참고했습니다.
@FilterDef
, @Filter
💡 위에서 봤던 Passage
엔티티 클래스에 아래 어노테이션들을 주입시킵니다.
name
: 적용할 필터 이름condition
: 필터의 조건name
: 정의할 필터 이름parameters
: 필터에 사용될 파라미터FilterManager
💡 필터 활성화와 비활성화를 위한 메소드를 생성합니다.
💡 필터 이름, 필터에 적용 시킬 파라미터 이름과 값을 받습니다.
💡 삭제된 데이터를 조회하기 전에 필터를 활성화합니다.
💡 데이터 조회가 끝난 후 필터를 비활성화해 기본 상태로 돌려놓습니다.
💡 JPA 메서드 호출 시 isDeleted 컬럼 조건 없이 원하는 데이터를 구분할 수 있습니다.
book_id = 1
인 데이터가 4개가 있고, id = 2
인 데이터가 삭제된 상태입니다.
isDeleted = false
book_id = 1
인 데이터를 모두 조회하면, 삭제된 데이터 1개를 제외한 3개의 데이터가 반환됩니다.
isDeleted = false
삭제된 데이터는 book id에 상관 없이 모두 조회하도록 되어 있어, book_id = 15
인 데이터도 같이 총 2개의 데이터가 출력됩니다.