【问题标题】:Spring Data JPA: deleteById does not delete record from database but derived delete method doesSpring Data JPA:deleteById 不会从数据库中删除记录,但派生的删除方法会
【发布时间】:2021-05-07 02:00:25
【问题描述】:

我在我的 Spring 应用程序中观察到一种奇怪的行为。不幸的是,我无法分享完整的代码,但基本上是这样的:

// the repository
@Repository
public interface InboxRepo extends JpaRepository<Inbox, Long> {}

// the service
@Transactional
public void deleteInbox(long id) {
    inboxRepo.deleteById(id);
}

调用deleteInbox() 时,没有异常或任何类型的错误,但Inbox 项没有从数据库中删除。设置spring.jpa.show-sql=true 表明甚至没有DELETE 语句,即无论出于何种原因,代码实际上并没有发出删除。

在存储库中定义派生删除方法时,删除工作有效,但对我来说还没有意义:

@Repository
public interface InboxRepo extends JpaRepository<Inbox, Long> {

    // this seems to work
    @Modifying
    @Query("delete from Inbox i where i.id = ?1")
    void delete(long id);
}

直接通过EntityManager 删除也可以。但是,“标准”JpaRepository 方法在这里不起作用的原因可能是什么?

【问题讨论】:

  • 其他 repo 方法能正常工作吗?
  • 是的,其他存储库工作正常。我怀疑这是某种相关的实体......
  • 问题是关于同一回购的其他方法,而不是其他回购)但没关系)考虑到deleteById内部确实findById(并且EmptyResultDataAccessException将在实体的情况下被抛出缺席)您是否在日志中看到生成的select ... 查询?如果不是,则可能实际上已经生成并执行了 delete 查询,但由于某种原因,该实体尚未被删除。

标签: spring jpa spring-data-jpa


【解决方案1】:

我找到了根本原因。还有另一个实体引用了Inbox,如下所示:

@OneToMany(mappedBy = "inbox", cascade = ALL, fetch = FetchType.EAGER)
private Set<Inbox> inbox = new HashSet<>();

FetchType.EAGER 与级联组合导致了问题,即,一旦 Inbox 被删除,此引用导致 Inbox 得到“重新持久化”。设置FetchType.LAZY 解决了这个问题。

【讨论】:

    猜你喜欢
    • 2013-05-05
    • 2020-03-06
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    相关资源
    最近更新 更多