如何解决Spring Data问题-派生的删除不起作用
我有一个spring boot应用程序(基于spring-boot-starter-data-jpa。我的配置绝对是最低的,只有一个表和一个实体。
我正在使用CrudRepository
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”语句,该语句选择所有具有SystemId和我指定的值的MyEntity行。使用mysql全局日志,我捕获了实际的物理sql,并在数据库上手动将其发布,并验证了它返回了大量的行。
因此,Spring或更确切地说是Hibernate试图选择必须删除的行,但实际上从不发出DELETE FROM语句。
根据note on Baeldung,这种选择语句是正常的,从某种意义上说,Hibernate将首先选择要删除的所有行,然后为每个行发出delete语句。
有人知道为什么这个派生的deleteBy方法不起作用吗?我的@Configuration上有@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
}
这有效。包括交易。但这不是必须的,我不需要添加该查询注释。
Here is a person的问题和我完全一样。但是,Spring开发人员很快就洗手了,并将其记为Hibernate问题,因此没有解决方案或解释。
哦,作为参考,我正在使用Spring Boot 2.2.9。
解决方法
tl; dr
全部在reference documentation中。这就是JPA的工作方式。 (我在洗手。)
详细信息
这两种方法有两种不同的作用:Long deleteBySystemId(String systemId);
通过给定的约束加载实体并最终发出EntityManager.delete(…)
,持久性提供者将延迟该延迟,直到事务提交为止。即调用后的代码不能保证更改已同步到数据库。反过来,这是由于JPA允许其实现实际执行此操作。不幸的是,Spring Data无法在此之上解决任何问题。 (更多的摩擦,更多的洗涤,再加上一点肥皂。)
reference documentation通过触发EntityManager
等生命周期事件来证明这种行为与@PreDelete
的行为(同样是JPA抽象,与Spring Data无关)。哪些用户希望被触发。
手动声明修改查询的第二种方法是声明要在数据库中执行查询 ,这意味着实体生命周期不会触发,因为实体不会得到提前实现。
但是,Spring开发人员很快洗手并将其记为Hibernate问题,因此在那里找不到解决方案或解释。
有详细的解释,说明了为什么其工作方式与故障单注释中的工作方式相同。甚至提供解决方案。解决方案和建议,以控制此行为的堆栈部分对此进行介绍。 (水龙头,伸手去拿毛巾。)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。