openJPA的0.9.7和1.0.0的構造型查詢均不支持distinct,但如果不使用構造型方式查詢又支持distinct,最后檢查JPQLExpressionBuilder.java的evalSelectClause(..)方法,發(fā)現(xiàn)是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中進行修改