当前位置: 首页 > 知识库问答 >
问题:

spring数据问题-派生删除不起作用

邓正真
2023-03-14

我有一个spring boot应用程序(基于spring-boot-starter-data-jpa。

我使用了CrudRepository 和几个findBy方法,这些方法都可以工作。而且我有一个派生的deleteBy方法--这不起作用。签名很简单:

public interface MyEntityRepository<Long, MyEntity> extends CrudRespository<> {
    Long deleteBySystemId(String systemId);
    // findBy methods left out
}

实体也很简单:

@Entity @Table(name="MyEntityTable")
public class MyEntity {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="MyEntityPID")
    private Long MyEntityPID;

    @Column(name="SystemId")
    private String systemId;

    @Column(name="PersonIdentifier")
    private String personIdentifier;

   // Getters and setters here, also hashCode & equals.
}

deleteBy方法不起作用的原因是它似乎只向数据库发出一个“select”语句,该语句选择所有的MyEntity行,这些行具有一个带有我指定值的SystemId。使用我的mysql全局日志,我捕获了实际的、物理的sql,并在数据库上手动发布它,并且验证它返回了大量的行。

所以spring,或者更确切地说是Hibernate,正在尝试选择它必须删除的行,但它实际上从未发出delete FROM语句。

根据Baeldung的一个注释,这个select语句是正常的,因为Hibernate将首先选择它想要删除的所有行,然后为其中的每一行发出delete语句。

有人知道为什么这个派生的deleteBy方法不能工作吗?我的@配置上有@TransactionManagementEnabled,调用的方法是@Transactional。mysql日志显示,spring设置了AutoCommit=0,因此似乎事务已正确启用。

我通过以下方式手动注释派生的delete方法来解决这个问题:

public interface MyEntityRepository<Long, MyEntity> extends CrudRespository<> {
    @Modifying
    @Query("DELETE FROM MyEntity m where m.systemId=:systemId")
    Long deleteBySystemId(@Param("systemId") String systemId);
    // findBy methods left out
}

这管用。包括交易。但这不应该是,我不应该需要添加查询注释。

这是一个和我有同样问题的人。然而,spring的开发人员很快就洗手了,并将其作为Hibernate问题一笔勾销,因此没有找到任何解决方案或解释。

哦,作为参考,我使用的是spring boot 2.2.9。

共有1个答案

衡玄裳
2023-03-14

都在参考文档里。这就是JPA的工作方式。(我在洗手。)

这两个方法执行两种不同的操作:长的deleteBySystemId(字符串systemId);通过给定的约束加载实体,并最终发出EntityManager.Delete(…),持久性提供程序将延迟它直到事务提交。即。调用后的代码不能保证更改已经同步到数据库。而这又是由于JPA允许它的实现真正做到了这一点。不幸的是,spring的数据根本无法解决这个问题。(多擦,多洗,再加一点肥皂。)

参考文档证明了该行为需要EntityManager(同样是一个JPA抽象,与spring数据无关)来触发用户期望触发的@predelete等生命周期事件。

第二种手动声明修改查询的方法是声明要在数据库中执行的查询,这意味着实体生命周期不会被激发,因为实体没有预先被物化。

然而,spring的开发人员很快就洗手了,并将其作为休眠问题一笔勾销,因此没有找到任何解决方案或解释。

有详细的解释为什么它的工作方式,它的工作方式,在评论的票证。甚至还有解决方案。解决办法和建议,使之与控制此行为的堆栈部分一起出现。(关上水龙头,伸手拿毛巾。)

 类似资料:
  • 我使用的是Kafka版本0.8.2。在开发过程中,我想我可能需要删除一个主题。所以我所做的是在服务器配置文件中放入以下一行,并启动两台kafka服务器。 当我需要删除一个主题并运行以下命令时, 现在距我运行“删除主题”命令已经17个小时了,但Kafka仍在向我显示该主题已标记为删除。是Kafka的虫子还是我在这里做错了什么?因为在我看来这不正常。有人能就此澄清一下吗?

  • 在Xcode5中,有一个删除派生数据的简单选项: 在组织者菜单中(cmd+shift+2): 但是Xcode6的新接口没有类似的选项。 有什么快速的方法可以删除这个槽Xcode6接口吗?

  • 在我的项目中,我使用Spring数据jpa。我有多对多关系的表格。我的实体: 和零件: 现在在Controller中,我尝试从表部分中删除一行: 但我有例外: 区分完整性约束冲突:“FK9Y4MKICYBLJWPENACP4298I49:PUBLIC.PARTS外键(ID\u导出)引用PUBLIC.EXPORT(ID)(1)”;SQL语句:/*删除com.aleksandr0412.demo.en

  • 和UserServiceImpl: 在前端,我创建了一个简单的表,如下所示: 现在,当我启动我的应用程序并单击删除按钮时,我在网站上出现了这样的错误:当前线程没有实际事务可用的EntityManager-不能可靠地处理“Remove”调用;嵌套异常是javax.persistence.TransactionRequiredException:当前线程没有实际事务可用的EntityManager-不

  • 我是一个初学者开发人员。我的应用程序中有一个SQLite数据库。我已经成功地为其添加了添加、删除和更新功能。我现在正在尝试实现滑动删除,但是,我面临着当前的问题:有时在我滑动并删除项目后,它会成功删除(从数据库中),有时不会,有时会删除上面的项目,有时会删除上面的项目2 id。我做了很多尝试和错误,但我无法确认为什么会发生这种情况。总是发生的是项目从视图中删除,因为它不再有自己的卡(我正在使用ca

  • 问题内容: 我试图通过执行以下循环来获取TreeMap的前10个元素: 该打印 工具,为什么可能不起作用? 更新 这是我的实现: 更新 这很有用:Java Map按值排序。 问题答案: public int compare(Integer a, Integer b) { if (base.get(a) >= base.get(b)) { return -1; } else { return 1;