JpaRepository - 删除方法 - 提示实体不存在

5
在进行删除操作时,JpaRepository 能否告诉我,我想要删除的 entity 不存在?我知道删除方法不返回 boolean 值,也不会抛出Exceptions异常。我还知道可以使用 exists() 或findOne()来查找实体再执行删除,但我只是好奇。有没有什么办法可以强制删除一个不存在的实体?我正在使用Spring Boot 1.5.1。下面是示例代码:
public HttpStatus deleteEventByTitle(String eventTitle) {
    try {
        eventRepository.deleteByTitle(eventTitle);
    } catch (EntityNotFoundException e) { // just showing what I want to do
        return HttpStatus.NOT_FOUND;
    }
    return HttpStatus.OK;
}


public interface EventRepository extends JpaRepository<Event, Long> {

    void deleteByTitle(String title);

}

将void更改为int,从而得到 int deleteByTitle(String title);。这将使返回受影响的行。因此,如果您有return> 0,则表示已删除某些内容。如果您想要一个像 deleteByTitleOrThrow(String title) 这样的额外方法,则可以创建一个...Impl类和一个额外的接口来扩展行为并将该方法添加到其中。 - andreim
3个回答

10

从Spring Data JPA(>=1.7.x)开始,我们可以使用派生deleteremove查询。它可以返回删除的实体数量或者删除的所有实体。

通过使用它,我们可以更新我们的代码为:

public interface EventRepository extends JpaRepository<Event, Long> {
    long deleteByTitle(String title);
}

如果实体不存在,我们可以抛出异常。

public HttpStatus deleteEventByTitle(String eventTitle) {
    long numOfEntriesDeleted = eventRepository.deleteByTitle(eventTitle);
    if(numOfEntriesDeleted != 1){
       return HttpStatus.NOT_FOUND;
    }
    return HttpStatus.OK;
}

1

在删除之前,您可以简单地检查它是否存在:

// Check if the ID is available
if (deviceRepository.existsById(id)) {
    deviceRepository.deleteById(id);
    //returnObject.setMessage("Deleted successfully !!");

} else {
    //returnObject.setMessage("The ID is not found");
}

3
在多线程环境中,这是不安全的,因为在数据库查询和删除之间,另一个查询可能已经删除了该实体。 - Daniel Pop

1
根据规范,这是不可能的,我也不知道有类似这样的功能。
我知道在使用Cassandra和Datastax时,您可以检查wasApplied()
唯一的解决方法是实现自己的deleteOrThrowException方法,并在找不到实体时抛出异常。
为了实现这一点,您可以添加一个
@Query("select count(event)>0 from Event e where eventTitle := eventTitle")
public boolean existsByTitle(String eventTitle);

嗯,我认为最好的方法是编写@Query("..") Boolean existsByTitle,因为Spring Data不支持existsByAttribute。 - sovas
已更新,附带示例。 - questionaire

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接