Hibernate JPA校验删除MySQL数据时出现SQL语法错误求助
嘿,我来帮你搞定这个SQL语法错误的问题!你遇到的情况是JPA生成的SQL漏了等于号,导致MySQL报1064错误,大概率是查询方法的写法或者JPQL语句出了问题。咱们一步步来修正:
1. 先确认数据库表结构
首先确保你的santa_connections表结构是正确的,以下是符合需求的DDL语句:
CREATE TABLE santa_connections ( id BIGINT AUTO_INCREMENT PRIMARY KEY, santa_name VARCHAR(255) NOT NULL, santa_last_name VARCHAR(255) NOT NULL, reciving_participant_name VARCHAR(255) NOT NULL, reciving_participant_last_name VARCHAR(255) NOT NULL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP );
2. JPA实体类(
SantaConnection.java) 实体类要和数据库表字段一一对应,注意映射注解的正确性:
import javax.persistence.*; import java.time.LocalDateTime; @Entity @Table(name = "santa_connections") public class SantaConnection { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(name = "santa_name", nullable = false) private String santaName; @Column(name = "santa_last_name", nullable = false) private String santaLastName; @Column(name = "reciving_participant_name", nullable = false) private String recivingParticipantName; @Column(name = "reciving_participant_last_name", nullable = false) private String recivingParticipantLastName; @Column(name = "created_at") private LocalDateTime createdAt; // 空参构造函数(JPA必需) public SantaConnection() {} // Getter & Setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getSantaName() { return santaName; } public void setSantaName(String santaName) { this.santaName = santaName; } public String getSantaLastName() { return santaLastName; } public void setSantaLastName(String santaLastName) { this.santaLastName = santaLastName; } public String getRecivingParticipantName() { return recivingParticipantName; } public void setRecivingParticipantName(String recivingParticipantName) { this.recivingParticipantName = recivingParticipantName; } public String getRecivingParticipantLastName() { return recivingParticipantLastName; } public void setRecivingParticipantLastName(String recivingParticipantLastName) { this.recivingParticipantLastName = recivingParticipantLastName; } public LocalDateTime getCreatedAt() { return createdAt; } public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; } }
3. DAO层(
SantaConnectionRepository.java) 这里提供两种正确的实现方式,同时指出你可能踩的坑:
方式一:Spring Data JPA方法命名(推荐,避免手写语法错误)
严格按照Spring Data的命名规范编写方法,它会自动生成正确的SQL:
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.transaction.annotation.Transactional; public interface SantaConnectionRepository extends JpaRepository<SantaConnection, Long> { @Modifying @Transactional void deleteBySantaNameOrRecivingParticipantNameAndSantaLastNameOrRecivingParticipantLastName( String santaName, String recivingParticipantName, String santaLastName, String recivingParticipantLastName); }
调用示例:
// 传入对应参数,实现需求中的删除逻辑 santaConnectionRepository.deleteBySantaNameOrRecivingParticipantNameAndSantaLastNameOrRecivingParticipantLastName( "Oscar", "Oscar", "Martinez", "Martinez" );
你可能犯的错误:
如果方法命名拼写错误(比如把字段名写错),或者逻辑运算符顺序混乱,JPA无法正确解析,就会生成缺失=的错误SQL。
方式二:手写@Query注解(适合复杂条件)
如果方法命名太冗长,也可以直接写JPQL或原生SQL,注意语法完整性:
JPQL版本
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import org.springframework.transaction.annotation.Transactional; public interface SantaConnectionRepository extends JpaRepository<SantaConnection, Long> { @Modifying @Transactional @Query("DELETE FROM SantaConnection sc WHERE " + "(sc.santaName = :name OR sc.recivingParticipantName = :name) " + "AND (sc.santaLastName = :lastName OR sc.recivingParticipantLastName = :lastName)") void deleteByMatchingNameAndLastName(@Param("name") String name, @Param("lastName") String lastName); }
调用示例:
santaConnectionRepository.deleteByMatchingNameAndLastName("Oscar", "Martinez");
原生SQL版本
@Modifying @Transactional @Query(value = "DELETE FROM santa_connections WHERE " + "(santa_name = :name OR reciving_participant_name = :name) " + "AND (santa_last_name = :lastName OR reciving_participant_last_name = :lastName)", nativeQuery = true) void deleteByMatchingNameAndLastNameNative(@Param("name") String name, @Param("lastName") String lastName);
你可能犯的错误:
手写时漏写=号(比如写成sc.santaName :name),或者实体类属性名和数据库列名混淆,都会导致SQL语法错误。
4. 错误原因总结
你遇到的SQL Error: 1064本质是生成的SQL缺失了=运算符,常见诱因:
- Spring Data方法命名不符合规范,导致JPA解析失败;
- 手写@Query语句时漏写
=或参数绑定错误; - 实体类字段和数据库列名映射不匹配,导致生成的SQL列名错误。
5. 注意事项
- 删除操作属于修改类操作,必须加上
@Modifying和@Transactional注解,否则Spring Data JPA会报错; - 如果使用原生SQL,要确保表名、列名和数据库完全一致;
- 测试时可以开启JPA的SQL日志(比如在application.yml中设置
spring.jpa.show-sql: true),直接查看生成的SQL语句,快速定位问题。
内容的提问来源于stack exchange,提问作者MajkelEight
相关产品推荐
相关产品推荐

