JPA / Hibernate选择查询返回重复记录

时间:2014-09-24 15:38:56

标签: java sql oracle hibernate jpa

我有一张表,比如,带有ID,State和User_ID的Instrument作为列。

所以我有这个JPA查询返回所有匹配的乐器记录 USER_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中有三个记录,其中包含仪器ID 1,2和3

我在hibernate上启用了show sql查询,并且查询在数据库上运行正常 并返回不同的记录。

Hibernate查询:

    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;
    }
}

不确定我错过了什么。

4 个答案:

答案 0 :(得分:11)

问题是,工具实体中的错误列已分配了@ID属性。

我已将其从User_ID中删除并将其添加到ID并且工作正常。

答案 1 :(得分:5)

我也遇到过同样的问题。     对于联系人表格,我仅将firstname列标记为@Id。     并且表具有多个具有相同firstname的行,因此具有相同firstname的第一行记录在整个结果集中被复制。     为了解决这个问题,我使用名字和姓氏作为id属性IdClass,并将其作为我的bean中的id类导入。     由于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;

}

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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