Spring Boot HTTP GET请求返回数据与MySQL数据库行不匹配问题
问题分析与解决方案
问题根源
你的contient表是订单与商品的关联中间表,主键应为**id_commande和id_produit的联合主键**,但当前实体类仅将id_commande标记为@Id。这会导致JPA映射查询结果时,把所有相同id_commande的行识别为同一个实体,最终返回数据出现覆盖、行数不匹配的问题。
修复步骤
1. 创建复合主键类
用@Embeddable定义符合JPA要求的复合主键类:
import jakarta.persistence.Embeddable; import java.io.Serializable; import java.util.Objects; @Embeddable public class ContientId implements Serializable { private Long id_commande; private Long id_produit; // JPA要求的无参构造器 public ContientId() {} public ContientId(Long id_commande, Long id_produit) { this.id_commande = id_commande; this.id_produit = id_produit; } // 必须实现equals和hashCode用于实体比较 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; ContientId that = (ContientId) o; return Objects.equals(id_commande, that.id_commande) && Objects.equals(id_produit, that.id_produit); } @Override public int hashCode() { return Objects.hash(id_commande, id_produit); } // getter和setter public Long getId_commande() { return id_commande; } public void setId_commande(Long id_commande) { this.id_commande = id_commande; } public Long getId_produit() { return id_produit; } public void setId_produit(Long id_produit) { this.id_produit = id_produit; } }
2. 修改Contient实体类
替换原有单一主键为复合主键:
import jakarta.persistence.EmbeddedId; import jakarta.persistence.Entity; import jakarta.persistence.Table; @Entity @Table(name="contient") public class Contient { @EmbeddedId private ContientId id; @Column(name="qte_produit") private int qte_produit; public Contient() {} public Contient(ContientId id, int qte_produit) { this.id = id; this.qte_produit = qte_produit; } // getter和setter public ContientId getId() { return id; } public void setId(ContientId id) { this.id = id; } public int getQte_produit() { return qte_produit; } public void setQte_produit(int qte_produit) { this.qte_produit = qte_produit; } }
3. 调整ContientRepo接口
更新JpaRepository的泛型主键类型:
import org.springframework.data.jpa.repository.JpaRepository; public interface ContientRepo extends JpaRepository<Contient, ContientId> { // 直接使用JPA默认的findAll()方法即可,无需自定义native查询 }
4. 简化Service层(可选)
改用JPA默认的查询方法:
import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service public class ContientService { private final ContientRepo contientRepo; public ContientService(ContientRepo contientRepo) { this.contientRepo = contientRepo; } @Transactional public List<Contient> findAllContient(){ return contientRepo.findAll(); } }
验证
重启应用后,用Postman请求/contient/all,返回数据将与数据库查询结果完全匹配。
内容的提问来源于stack exchange,提问作者Oukkal Yacine
相关产品推荐
相关产品推荐

