【问题标题】:JPA/Hibernate select query returning duplicate recordsJPA/Hibernate 选择查询返回重复记录
【发布时间】:2014-11-19 04:36:03
【问题描述】:

我有一个表,比如 Instrument,ID、State 和 User_ID 作为列。

所以我有这个 JPA 查询来返回所有具有匹配的仪器记录 用户 ID。

   query = manager.createQuery("SELECT instrument from Instrument instrument
             where instrument.User_ID=:User_ID",Instrument.class);
   query.setParameter("User_ID", User_ID);

   List<Instrument> instruments=  query.getResultList();

   for(Instrument instrument:instruments){
            System.out.println("Instrument ID  "+instrument.getID());
              // using sysout as it is not prod code yet
        }

它只返回与匹配记录重复的第一条记录。

11:13:01,703 INFO  [stdout] (http-/127.0.0.1:8080-1) Instrument ID   1
11:13:01,704 INFO  [stdout] (http-/127.0.0.1:8080-1) Instrument ID   1
11:13:01,704 INFO  [stdout] (http-/127.0.0.1:8080-1) Instrument ID   1

我在 Db 中有 3 条记录,仪器 ID 分别为 1、2 和 3

我在休眠时启用了 show sql 查询,查询直接在数据库上运行良好 并返回不同的记录。

休眠查询:

    select instrumentjdo0_.User_ID as member_U1_0_, instrumentjdo0_.ID as ID2_0_, 
instrumentjdo0_.state as state4_0_ from instrument instrumentjdo0_ where instrumentjdo0_.User_ID=?

仪器实体

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;




@Entity
@Table(name = "instrument")
public class Instrument{

    @Id
    @Column(name="User_ID", length=9, unique=true, nullable=false)
    String user_ID;

    @Column(name="ID",nullable=false)
    String ID;


    @Column(name="state",nullable=false)
    String state;

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getUserID() {
        return user_ID;
    }

    public void setUserID(String userID) {
        this.user_ID = userID;
    }


    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }
}

不知道我错过了什么。

【问题讨论】:

  • 您的问题中好像放错了Query,再检查一遍 --> User_ID=: "user_ID",
  • 是的,你是对的..修复它!谢谢!
  • 能否将hibernate生成的查询添加到您的问题中。
  • 我也添加了休眠查询
  • 好的,查询看起来不错。现在你怎么能说查询多次返回相同的记录?您是如何迭代列表的,能否请您也添加该代码?

标签: java sql oracle hibernate jpa


【解决方案1】:

问题是仪器实体中的错误列分配了@ID 属性。

我从User_ID 中删除了它,并将其添加到ID,它工作正常。

【讨论】:

  • 但这不会在正确运行查询时导致重复记录,因此您在 DB 中的任何记录都具有相同的 User_ID 值?
  • 是的,与同一用户关联的所有记录都具有相同的 User_ID。
  • 哦,好吧,那么这个陈述在您的问题中具有误导性——I enabled show sql query on hibernate and the query runs fine on the Database directly and returns distinct records.
  • 令人惊讶的是,它确实返回了不同的记录。我认为hibernate不会直接返回结果集,而是根据@ID等对结果进行某种处理。
  • 遇到了同样的问题,但我没有备用列来放置@Id,因此我创建了一个新列。
【解决方案2】:

我也遇到过同样的问题。 对于联系人表,我仅将firstname 列标记为@Id。 并且表有多个具有相同firstname 的行,因为具有相同firstname 的第一行记录在整个结果集中被重复。 为了解决这个问题,我使用名字和姓氏作为 id 属性创建了IdClass,并将其作为 id 类导入到我的 bean 中。 由于firstnamelastname 一起形成了独特的组合,它解决了我的问题。

Idclass 如下

public class ContactKey implements Serializable{

    protected String firstName;
    protected String lastName;

    public boolean equals(final Object inObject) {
        if (null != inObject) {
            if (inObject.getClass().equals(this.getClass())) {
                CqCamAdminKey siteKey = (CqCamAdminKey) inObject;
                return (null != this.getFirstName() && this.getFirstName().equals(siteKey.getFirstName()) && null != this.getLastName() && this.getLastName().equals(siteKey.getLastName()));
            }
        }
        return super.equals(inObject);
    }

    public int hashCode() {
        if (this.getFirstName() != null && this.getLastName() != null) {
            return this.getFirstName().hashCode() + this.getLastName().hashCode();
        }
        return super.hashCode();
    }
}

bean 类如下

@IdClass(contactKey.class)
public abstract class CqCamAdminDataBean implements DataModelConstants{

    private static final long serialVersionUID = 7686374823515894764L;

    @Id
    @JsonIgnore
    @XmlTransient
    @Column(name = FIRST_NAME)
    protected String firstName;


    @Id
    @JsonIgnore
    @Column(name = LAST_NAME)
    protected String lastName;

}

【讨论】:

【解决方案3】:

@Id 列的问题,如果我们仔细检查,@Id 列的值对于所有行都是相同的。因此,hibernate/JPA 无法获取不同的记录,它只是使用此 @Id 获取第一条记录并返回它的重复记录。

解决方案 - 将 @IdClass 与导致唯一行而不是重复行的列一起使用。

【讨论】:

    【解决方案4】:

    确保在您的 JPQL 查询中指定 DISTINCT"SELECT DISTINCT instrument from Instrument instrument where instrument.User_ID=:User_ID"。对于标量查询,DISTINCT 实质上会从结果集中删除底层重复项。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-24
      • 1970-01-01
      • 2021-09-14
      相关资源
      最近更新 更多