openJPA的0.9.7和1.0.0的构造型查询均不支持distinct,但如果不使用构造型方式查询又支持distinct,最后检查JPQLExpressionBuilder.java的evalSelectClause(..)方法,发现是openJPA中的问题,我将其修改为:
private Expression evalSelectClause(QueryExpressions exps) {
if (exps.operation != QueryOperations.OP_SELECT)
return null;
JPQLNode selectNode = root();
JPQLNode constructor = selectNode.findChildByID(JJTCONSTRUCTOR, true);
if (constructor != null) {
// build up the fully-qualified result class name by
// appending together the components of the children
String resultClassName = assemble(left(constructor));
exps.resultClass = resolver.classForName(resultClassName, null);
// now assign the arguments to the select clause as the projections
JPQLNode selectClause = selectNode.findChildByID(JJTSELECTCLAUSE, false);
if (selectClause != null && selectClause.hasChildID(JJTDISTINCT))
exps.distinct = exps.DISTINCT_TRUE | exps.DISTINCT_AUTO;
else
exps.distinct = exps.DISTINCT_FALSE;
return assignProjections(right(constructor), exps);
} else {
JPQLNode selectClause = selectNode.
findChildByID(JJTSELECTCLAUSE, false);
if (selectClause != null && selectClause.hasChildID(JJTDISTINCT))
exps.distinct = exps.DISTINCT_TRUE | exps.DISTINCT_AUTO;
else
exps.distinct = exps.DISTINCT_FALSE;
// handle SELECT clauses
JPQLNode expNode = selectNode.
findChildByID(JJTSELECTEXPRESSIONS, true);
if (expNode == null)
return null;
int selectCount = expNode.getChildCount();
JPQLNode selectChild = firstChild(expNode);
// if we are selecting just one thing and that thing is the
// schema's alias, then do not treat it as a projection
if (selectCount == 1 && selectChild != null &&
selectChild.getChildCount() == 1 &&
onlyChild(selectChild) != null &&
assertSchemaAlias().
equalsIgnoreCase(onlyChild(selectChild).text)) {
return null;
} else {
// JPQL does not filter relational joins for projections
exps.distinct &= ~exps.DISTINCT_AUTO;
return assignProjections(expNode, exps);
}
}
}
使用方式为:
select DISTINCT new com.wile.test.AData(a.id, a.name,..) from A where a.id=?1
目前已向openJPA提出此bug(bug-id:OPENJPA-420),希望他们能在1.0.1中进行修改