Java Persistence / JPQL中的Group By

时间:2014-10-20 04:28:08

标签: jpa jpql

我有一个Entity类,它有@ManyToOne关系。我需要在SQL查询中使用GROUP BY。 我写了一个JPQL但它不起作用。我的代码是:

    @NamedQuery(name = "AssetDepModel.findByAssedId", 
                query = "SELECT dep FROM AssetDepModel dep "
                        + "JOIN dep.faDetails fad "
                        + "WHERE fad.assetId.assId = :assetId_passed "
                        + "GROUP BY dep.faDetails,dep.faDetails.id,dep.fiscalModel.fyId,dep.depAmt,dep.depId,dep.depMethodId,dep.depRate,dep.depTypeId,dep.quarterId,dep.createdDt,dep.createdBy,dep.updatedDt,dep.updatedby "
                        + "ORDER BY fad.id")

public class AssetDepModel implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    public static final String FIND_BY_ASSET_ID = "AssetDepModel.findByAssedId";
    public static final String FIND_BY_DETAIL_ID = "AssetDepModel.findByDetailId";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "dep_id")
    private int depId;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "fiscal_id", referencedColumnName = "fy_id")
    private FiscalYrModel fiscalModel;

    @Column(name = "quarter_id")
    private int quarterId;

    @ManyToOne
    @JoinColumn(referencedColumnName = "id", name = "fa_details_id")
    private FADetailsModel faDetails;

    @Column(name = "dep_type_id")
    private int depTypeId;

    @Column(name = "dep_method_id") 
    private int depMethodId;

    @Column(name = "dep_rate")
    private Double depRate;

    @Column(name = "dep_amt")
    private Double depAmt;

    @Column(name = "created_dt")
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdDt;

    @Column(name = "created_by")
    private int createdBy;

    @Column(name = "updated_dt")
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedDt;

    @Column(name = "updated_by")
    private int updatedby;

我尝试了这段代码,但在调用JPQL时,总是会出错,说Select中的对象不包含在Group By子句中。 我需要根据外键字段进行GROUP BY。 我收到以下错误:

Internal Exception: com.microsoft.sqlserver.jdbc.SQLServerException: Column
'inv_asset_depreciation.fa_details_id' is invalid in the select list because 
it is not contained in either an aggregate function or the GROUP BY clause.
Error Code: 8120
Call: SELECT t0.dep_id, t0.created_by, t0.created_dt, t0.dep_amt, t0.dep_method_id,
t0.dep_rate, t0.dep_type_id, t0.quarter_id, t0.updated_dt, t0.updated_by, 
t0.fa_details_id, t0.fiscal_id FROM inv_asset_depreciation t0, fiscal_yr t2,
inv_fixed_asset_detail_mcg t1 WHERE ((t1.asset_id = ?) AND ((t1.id = t0.fa_details_id)
AND (t2.fy_id = t0.fiscal_id))) GROUP BY t1.id, t1.asset_given_name,
t1.brand_name_description, t1.created_by, t1.created_date, 
t1.dispose_dt_en,t1.dispose_dt_np, t1.dispose_value, t1.req_form_no, 
t1.start_use_dt_en,t1.start_use_dt_np,t1.update_count, t1.updated_by, 
t1.updated_date, t1.asset_id,t1.dept_id, t1.status, t1.id,t2.fy_id, t0.dep_amt,
t0.dep_id, t0.dep_method_id,t0.dep_rate, t0.dep_type_id,t0.quarter_id, 
t0.created_dt, t0.created_by,t0.updated_dt, t0.updated_by 
ORDER BY t1.id
    bind => [1 parameter bound]
Query: ReportQuery(name="AssetDepModel.findByAssedId" referenceClass=AssetDepModel
sql="SELECT t0.dep_id, t0.created_by, t0.created_dt, t0.dep_amt,
t0.dep_method_id,t0.dep_rate,t0.dep_type_id, t0.quarter_id, t0.updated_dt,
t0.updated_by, t0.fa_details_id,t0.fiscal_id FROM inv_asset_depreciation t0,
fiscal_yr t2, inv_fixed_asset_detail_mcg t1 WHERE ((t1.asset_id = ?) 
AND ((t1.id = t0.fa_details_id) AND (t2.fy_id = t0.fiscal_id))) 
GROUP BY t1.id, t1.asset_given_name, t1.brand_name_description, 
t1.created_by,t1.created_date, t1.dispose_dt_en, t1.dispose_dt_np,
t1.dispose_value, t1.req_form_no, t1.start_use_dt_en, t1.start_use_dt_np,
t1.update_count, t1.updated_by, t1.updated_date,t1.asset_id, t1.dept_id,
t1.status, t1.id, t2.fy_id, t0.dep_amt, t0.dep_id, t0.dep_method_id,
t0.dep_rate, t0.dep_type_id, t0.quarter_id, t0.created_dt, 
t0.created_by, t0.updated_dt,t0.updated_by ORDER BY t1.id")

我修改了这样的一点:

@SuppressWarnings("unchecked")
    public List<Object> findByAssetIdForSaleWriteOff(int assetId){
        Query query = getEntityManager().createQuery("SELECT fad.id,dep.depAmt FROM AssetDepModel dep "
                    + "JOIN dep.faDetails fad "
                    + "WHERE fad.assetId.assId = "+assetId+" "
                    + "GROUP BY fad.id,dep.depAmt "
                    + "ORDER BY fad.id",AssetDepModel.class);

        return (List<Object>)query.getResultList();
    }
List<Object> objList = assetDepEJB.findByAssetIdForSaleWriteOff(faObj.getAssId());
            Double amountDepTillNow = 0.0;
            int fadId = 0;
            int i=0;
            for (Iterator<Object> iterator3 = objList.iterator(); iterator3
                    .hasNext();) {
                Object[] obj = (Object[]) iterator3
                        .next();
                if (i>0) {
                    if (fadId != (Integer) obj[0]) {
                        break;
                    }
                }
                fadId = (Integer) obj[0];
                amountDepTillNow += (Double)obj[1];
                i++;

            }

它对我有用但是如果还有另一种有效的方式,那就请我做。

0 个答案:

没有答案