我有一个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++;
}
它对我有用但是如果还有另一种有效的方式,那就请我做。