【问题标题】:Query returning a lot of repeated records查询返回大量重复记录
【发布时间】:2019-07-29 04:36:18
【问题描述】:

我尝试从两个表(Statement、AppCurContract)进行查询,但收到很多重复记录。即使我只从 Statement 进行查询,我也会收到相同的结果。 当我将 appCurContracts 字段添加到 Statement bean 时,它就开始了。

我在这里发现了同样的问题Spring Data JPA query return repeated row instead of actual data, why?

但我在两个表中都有唯一键。我做错了什么?

这是我的代码

import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.EqualsAndHashCode;

import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Entity
@Table
@Data
@EqualsAndHashCode(exclude = "appCurContracts")
public class Statement {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String numStatement;
    @Column(updatable = false)
    @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime dateTimeSubmStatement;
    private int filialId;
    private int myself;
    private int status;
    private Date modifyDate;
    private String nameNonResident;
    private String email;
    private Integer typeStatement;
    @OneToMany(mappedBy = "statement", cascade = CascadeType.ALL)
    private Set<AppCurContract> appCurContracts;
    public Statement() {
        super();
    }

    public Statement(String nameDocument, String numStatement, LocalDateTime dateTimeSubmStatement, String jurPerson, String iin_bin, int filialId, int myself, int status, Date modifyDate, String nameNonResident, String contractNum, Date contractDate, String phone, String email, Integer typeStatement, String json, String iinBinRight, AppCurContract... appCurContracts) {
        this.numStatement = numStatement;
        this.dateTimeSubmStatement = dateTimeSubmStatement;
        this.filialId = filialId;
        this.myself = myself;
        this.status = status;
        this.modifyDate = modifyDate;
        this.nameNonResident = nameNonResident;
        this.email = email;
        this.typeStatement = typeStatement;
        this.appCurContracts = Stream.of(appCurContracts).collect(Collectors.toSet());
        this.appCurContracts.forEach(x -> x.setStatement(this));
    }

    public void setAppCurContracts(Set<AppCurContract> appCurContracts) {

        for (AppCurContract child : appCurContracts) {

            child.setStatement(this);
        }
        this.appCurContracts = appCurContracts;
    }
}
import lombok.Data;
import javax.persistence.*;

@Entity
@Data
public class AppCurContract {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToOne
    @JoinColumn()
    private Statement statement;
    private String jurPerson;
    private String iin_bin;
    private String nameDocument;
    private String contractNum;
    private String contractDate;

    public AppCurContract() {
        super();
    }

    public AppCurContract(String jurPerson, String iin_bin, String nameDocument, String contractNum, String contractDate) {
        this.jurPerson = jurPerson;
        this.iin_bin = iin_bin;
        this.nameDocument = nameDocument;
        this.contractNum = contractNum;
        this.contractDate = contractDate;
    }
}


public interface StatementRepo extends JpaRepository<Statement, Long> {

    @Query("SELECT d FROM Statement d JOIN d.appCurContracts e" +
            " WHERE d.status = ?1")

//    @Query("SELECT d FROM Statement d WHERE d.status = ?1")

    List<Statement> findByStatus(Integer status);

    List<Statement> findStatementsByEmailEquals(String email);
}

编辑 仔细查看 JSON 结果,我发现结果不仅是重复的,而且字段“appCurontract”包含嵌套语句,然后又包含“appCurContract”(相互嵌套)等。我认为是无限期的。 我预计只有 5 条记录。

【问题讨论】:

  • “JOIN d.appCurContracts e”的目的是什么?
  • 仔细查看 JSON 结果,我发现结果不仅是重复的,而且字段“appCurontract”包含嵌套语句,然后又包含“appCurContract”(相互嵌套)等。我无限期地这么认为。那么你面临的具体问题是什么。 JSON 与您期望的不一样,或者从数据库加载的数据与您期望的不一样,因为它们是完全不同的两件事。
  • 从数据库加载的数据不符合我的预期

标签: java spring hibernate spring-data-jpa


【解决方案1】:

自己定义哈希码方法,必要条件为set uses this to check for duplicates。您的代码(在您的存储库实现中)将变为:

List<Statement> findDistinctByEmail(String email);

而且你不应该需要查询注释。

【讨论】:

  • 我在 Statement 中添加了 hashcode 方法,其中包含除 appCurContracts 之外的所有字段。但结果相同。
  • 我看不出你的帖子有什么不同,你能用 EDIT 名字标记编辑吗?
  • 就在帖子的最后。标记为 EDIT。
【解决方案2】:

移除 Statement 类的 setAppCurContracts 方法。没必要。

移除@Query 的注解并使用findByStatus 方法。

【讨论】:

    【解决方案3】:

    我找到了解决问题的方法。我在 AppCurContract 类的 Statement 字段中添加了 @JsonIgnore 注释。

    public class AppCurContract {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    
    @JsonIgnore
    @ManyToOne
    @JoinColumn()
    private Statement statement;
    private String jurPerson;
    private String iin_bin;
    private String nameDocument;
    private String contractNum;
    private String contractDate;
    

    感谢大家的参与

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      • 2013-05-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多