JPA - 从子集中选择实体

时间:2013-12-03 17:24:39

标签: java jpa eclipselink jpql

我有一个名为Fee的实体类。执行初始查询后,如果返回多个Fee,我只想在第一个查询返回的行上添加一些(WHERE)条件。由于代码片段胜过千言万语,因此它是:

// Results of initial query
List<Fee> fees = queryFindFees.getResultList();
if (fees == null || fees.size() <= 0)
    return null;
if (fees.size() == 1) {
    Fee f = fees.get(0);
    jpa.refresh(f);
    return f;
}

// More than one fee found
String sqlBase = "SELECT f FROM Fee f WHERE f IN :fees";
String sqlComplete = sqlBase/* + " AND f.isValid = ?1"*/;
queryFindFees = jpa.createQuery(sqlComplete);
queryFindFees.setParameter("fees", fees);
// Commented out for test
// queryFindFees.setParameter(1, "Y");
List<Fee> specFees = queryFindFees.getResultList();

现在,因为我实际上要求EntityManager返回上一个查询中已经返回的所有费用,我希望得到相同的结果集。相反,列表specFees始终为空。

我做错了什么?

提前致谢,

卢卡

编辑1:实体课程费用详情

@Entity
public class Fee implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(unique = true, nullable = false)
    private long id;

    @Column(nullable = false, length = 1)
    private String isValid;

    ...

    @Override
    public boolean equals(Object arg0) {
        if (!(arg0 instanceof Fee))
            return false;
        Fee f0 = (Fee) arg0;
        return f0.getId() == this.getId();
    }
}

生成的SQL(sqlComplete变量)符合预期:

SELECT f FROM Fee f WHERE f IN :fees

编辑2:正如Deepak所建议的那样,使用ID集合起作用:

String sqlBase = "SELECT f FROM Fee f WHERE f.id IN :feesIds";
String sqlComplete = sqlBase/* + " AND f.isValid = ?1"*/;
List<Long> feesIds = new ArrayList<Long>();
for (Fee f : fees) {
    feesIds.add(f.getId());
}
queryFindFees = jpa.createQuery(sqlComplete);
queryFindFees.setParameter("feesIds", feesIds);

使用此代码可以查询(返回所有原始费用),但是如果可能,我希望避免使用for循环,因为Fee实例的数量可能非常大...

1 个答案:

答案 0 :(得分:0)

看起来你重写的equals方法正在创建问题。使用你的id Long对象并使用下面重写的方法。或者你也可以使用这个查询

SELECT f FROM Fee f WHERE f.id IN :fees 

这次您的费用参数将包含Fee objects

的ID列表
@Entity
public class Fee implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(unique = true, nullable = false)
private Long id;

@Column(nullable = false, length = 1)
private String isValid;

...

 @Override
 public boolean equals(Object arg0) {
    if (!(arg0 instanceof Fee))
        return false;
    Fee f0 = (Fee) arg0;
    return f0.getId().equals(this.getId());
  }
}