spring data JPA中“deleteByXXX”使用总结
项目环境:spring boot+JPA+MySQL,JDK1.8deleteById根据主键id删除,最为普遍的用法,由JPA提供的方法,无需在repository层声明,也无需加事物注解 @Transactional@Overridepublic void delete(String id) {studentRepository.deleteById(id);}deleteByXXX根据XXX
·
项目环境:spring boot+JPA+MySQL,JDK1.8
deleteById
根据主键id删除,最为普遍的用法,由JPA提供的方法,无需在repository层声明,也无需加事物注解 @Transactional
@Override
public void delete(String id) {
studentRepository.deleteById(id);
}
deleteByXXX
根据XXX删除,需要在repository层声明,也需在service层方法加事物注解 @Transactional
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteByName(String name) {
studentRepository.deleteByName(name);
}
先delete后add
需求:根据”name“删除一条数据后、再新增一条数据,并且数据库中”name“是有唯一性约束的
错误代码:
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteAndAdd(Student student) {
studentRepository.deleteByName(student.getName());
studentRepository.save(student);
}
问题:
错误输出日志中已说明:由数据库唯一性约束导致。
原因分析:
输出JPA的sql执行语句看看:
很明显,并未做删除操作,就执行了插入操作,所以出现”name“重复的情况。
从网上找答案:
jpa是在整个事务完了之后再执行delete语句的。 通常,一个实体在被删除之前必须进行管理,因此JPA提供程序将首先加载(您看到的查询)该实体,然后发出删除。
我的理解是,delete操作是在deleteAndAdd()方法执行完毕后才执行(这里不确定)
两种解决办法:
- 调用flush()方法
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteAndAdd(Student student) {
studentRepository.deleteByName(student.getName());
studentRepository.flush();
studentRepository.save(student);
}
- 在Repository层使用jpql语句
@Repository
public interface StudentRepository extends BaseRepository<Student, String> {
/**
* 根据姓名删除学生
* @param name 学生姓名
*/
@Modifying
@Query(value = "delete from Student s where s.name = :name")
void deleteByName(@Param String name);
}
更多推荐
已为社区贡献1条内容
所有评论(0)