Spring boot JPA CriteriaQuery无法为日期差异之和找到合适的构造函数

Spring boot JPA CriteriaQuery无法为日期差异之和找到合适的构造函数,spring-boot,jpa,spring-data-jpa,criteriaquery,Spring Boot,Jpa,Spring Data Jpa,Criteriaquery,我知道这个问题看起来很相似,但我认为对我来说情况不同 这是异常消息 获取数据时出现异常(/periodicReport/userReport): org.hibernate.hql.internal.ast.QuerySyntaxException:无法找到 类上的适当构造函数 [com.analytics.entity.projections.UserParticipantCountAndDurationImpl]。 预期参数为:java.util.UUID、long、java.util.Da

我知道这个问题看起来很相似,但我认为对我来说情况不同

这是异常消息

获取数据时出现异常(/periodicReport/userReport): org.hibernate.hql.internal.ast.QuerySyntaxException:无法找到 类上的适当构造函数 [com.analytics.entity.projections.UserParticipantCountAndDurationImpl]。 预期参数为:java.util.UUID、long、java.util.Date[选择 新的 com.analytics.entity.projections.UserParticipantCountAndDurationImpl(generatedAlias0.userID, count(不同的generatedAlias0.userID)、sum(函数('TIMEDIFF')和, generatedAlias0.endTime,generatedAlias0.startTime))来自 com.analytics.entity.ConferenceParticipant as generatedAlias0组按generatedAlias0.userID排序依据:param0 desc]

我希望总和是长的,我已经在条件查询中指定了它。 我不知道日期是在哪里定义的

建筑物的狙击手

Expression<Long> sum = criteriaBuilder.sum(
            criteriaBuilder.function(
                    "TIMEDIFF",
                    Long.class,
                    participantRoot.<Date>get("endTime"),
                    participantRoot.<Date>get("startTime")
            )
    );
    Expression<Long> count = criteriaBuilder.countDistinct(participantRoot.get("userID"));
    reportQuery.select(criteriaBuilder.construct(
            UserParticipantCountAndDurationImpl.class,
            participantRoot.get("userID").as(UUID.class).alias(USER_ID),
            count.as(Long.class).alias(PARTICIPANTS),
            sum.as(Long.class).alias(PARTICIPANT_DURATION)
    ));

是的,我已经尝试更改构造函数的签名。在这种情况下,查询将运行,但是由于它是java.util.Date,因此您需要一个带有要从timediff函数中提取的单元名称的表达式

public static class TimeUnitExpression extends BasicFunctionExpression<String> implements Serializable {

    public TimeUnitExpression(CriteriaBuilderImpl criteriaBuilder, Class<String> javaType,
            String functionName) {
        super(criteriaBuilder, javaType, functionName);
    }

    @Override
    public String render(RenderingContext renderingContext) {
        return getFunctionName();
    }
}
公共静态类TimeUnitExpression扩展了BasicFunctionExpression实现了可序列化{
公共时间单位表达式(CriteriaBuilderImpl criteriaBuilder,类javaType,
字符串(函数名){
super(criteriaBuilder、javaType、functionName);
}
@凌驾
公共字符串渲染(RenderingContext RenderingContext){
返回getFunctionName();
}
}
所以你的求和表达式变成了

    Expression<Long> sum = criteriaBuilder.sum(
            criteriaBuilder.function(
                    "TIMEDIFF",
                    Long.class,
                    new TimeUnitExpression(null, String.class, "MILLISECOND"),
                    participantRoot.<Date>get("endTime"),
                    participantRoot.<Date>get("startTime")
            )
    );
Expression sum=criteriaBuilder.sum(
criteriaBuilder.function(
“时间差异”,
长时间上课,
新的TimeUnitExpression(null,String.class,“毫秒”),
participantRoot.get(“结束时间”),
participantRoot.get(“开始时间”)
)
);

TIMEDIFF返回日期时间作为结果,因此不能将其强制转换为Long或double,原始结果中的Sql对象是DateTime。
我可以通过使用函数从datetime获取分钟数来解决这个问题。但我通过求和的日期时间和unixtimestap的差来解决这个问题。由于UNIXTTIMESTAMP总是长的,我可以将其转换为long或BigInteger

Sorry@tremendous7,您在这里谈论TIMESTAMDIFF函数,TIMEDIFF不需要任何单位。我已经解决了问题,谢谢你的回复
    Expression<Long> sum = criteriaBuilder.sum(
            criteriaBuilder.function(
                    "TIMEDIFF",
                    Long.class,
                    new TimeUnitExpression(null, String.class, "MILLISECOND"),
                    participantRoot.<Date>get("endTime"),
                    participantRoot.<Date>get("startTime")
            )
    );