查询返回大量重复记录

时间:2019-07-29 04:36:18

标签: java spring hibernate spring-data-jpa

我尝试从两个表(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”(彼此嵌套),依此类推。我无限期地认为

4 个答案:

答案 0 :(得分:0)

您可以在查询中添加distinct关键字:

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

或者,如果您使用的是EntityManager的查询,则可以使用提示:QueryHints.HINT_PASS_DISTINCT_THROUGH

答案 1 :(得分:0)

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

List<Statement> findDistinctByEmail(String email);

而且您不需要查询注释。

答案 2 :(得分:0)

删除Statement类上的 setAppCurContracts 方法。没必要。

删除@Query的注释,并使用 findByStatus 方法。

答案 3 :(得分:0)

我找到了解决问题的办法。我在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;

谢谢大家的参与