Kim-Baek 개발자 이야기

jpa delete entity 시, 삭제가 안되는 경우 본문

개발/Spring

jpa delete entity 시, 삭제가 안되는 경우

김백개발자 2021. 7. 13. 10:39

Jpa를 사용하다가, entity를 repository를 통해서 삭제했는데 DB에 값이 남아있고 삭제가 되지 않는 경우가 있다. 어떤 경우인지 우선 살펴보겠다.

첫 번째로 유저 엔티티이다.

@Entity
public class Users implements Serializable {

   @Id
   @GeneratedValue
   private long id;

   private String name;

   @OneToMany(mappedBy = "user", fetch = FetchType.EAGER, cascade = {CascadeType.ALL})
   private Set<UserRoleUser> userRoleUser;

   // GETTERS AND SETTERS
}

두 번째로 유저 롤 엔티티이다.

@Entity
public class UserRole implements Serializable {

   @Id
   @GeneratedValue
   private long id;

   private String roleName;

   @OneToMany(mappedBy = "userrole", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
   private Set<UserRoleUser> userRoleUser;

   // GETTERS AND SETTERS
}

 

그리고 두 개를 모두 가지고 있는 유저롤유저 엔티티 이다.

@Entity
public class UserRoleUser implements Serializable {

   @Id
   @GeneratedValue
   private long id;

   @ManyToOne
   @JoinColumn(name = "fk_userId")
   private Users user;

   @ManyToOne
   @JoinColumn(name = "fk_userroleId")
   private UserRole userrole;

   // GETTERS AND SETTERS
}

그리고 이를 관리하는 @Repository 인터페이스이다. JpaRepository를 extend 해서 사용하고 있다.

@Repository
@Transactional
public interface UserRoleUserRepository extends JpaRepository<UserRoleUser, Long> {

}
@SpringBootApplication
@Configuration
public class Application {

   public static void main(String[] args) {
       ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

       UserRoleUserRepository userRoleUserRepository = context.getBean(UserRoleUserRepository.class);

       Iterable<UserRoleUser> findAll = userRoleUserRepository.findAll(QUserRoleUser.userRoleUser.id.gt(0));

       for (UserRoleUser userRoleUser : findAll) {
           userRoleUserRepository.delete(userRoleUser);
       }

   }

}

이렇게 삭제 요청을 보냈을 경우에 원하는 것은 UserRoleUser 엔티티가 전체가 삭제되는 것이다. 그렇지만 아무것도 일어나지 않는다.

문제는 조인이 되어있기 때문이다. UserRoleUser 를 삭제하려고 했을 경우에, 매핑되어 있는 부모 오브젝트에서 체크를 하게 되는데 여기에서는 변경사항이 없기 때문에 DB를 변경하지 않고, 마찬가지로 UserRoleUser의 삭제도 이루어지지 않는다.

 

해결방법은 두 가지가 있다.

1. delete 메소드가 아닌 deleteById 를 사용한다. deleteById는 삭제를 하기 전에 부모의 오브젝트에서 체크를 하는 과정이 없어서 그냥 삭제가 된다.

 

2. deleteInBatch 를 사용한다. 

두 개 중 어떤 방식을 사용하더라도 정상적으로 동작하기 때문에 테스트를 해보고 사용하길 바란다.

반응형
Comments