如何解决JPA CriteriaQuery 无法为日期差异总和找到合适的构造函数
我知道这个问题看起来很相似,但我认为对我来说情况不同
这是异常信息
获取数据时出现异常 (/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(生成的Alias0.userID, 计数(不同的生成别名0.userID),总和(函数('TIMEDIFF', generatealias0.endTime,generatedalias0.startTime))) 来自 com.analytics.entity.ConferenceParticipant 作为 generatealias0 group bygeneratedalias0.userID order by :param0 desc]
我期望总和为 Long 并且我在标准查询中指定了它。 我不知道日期在哪里定义
为建造者的 snipet
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)
));
有问题的课程
@Data
@NoArgsConstructor
public class UserParticipantCountAndDurationImpl implements UserParticipantCountAndDuration,Serializable {
private UUID userID;
private long participants;
public long participantDuration;
public UserParticipantCountAndDurationImpl(
UUID userID,long participants,long participantDuration
) {
this.userID = userID;
this.participants = participants;
this.participantDuration = participantDuration;
}
}
是的,我尝试更改构造函数的签名。在这种情况下,查询将运行,但随后抛出 CastException,因为它是 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();
}
}
所以你的求和表达式变成
Expression<Long> sum = criteriaBuilder.sum(
criteriaBuilder.function(
"TIMEDIFF",Long.class,new TimeUnitExpression(null,String.class,"MILLISECOND"),participantRoot.<Date>get("endTime"),participantRoot.<Date>get("startTime")
)
);
,
TIMEDIFF 返回日期时间作为结果,因此不能强制转换为 Long 或 double,原始结果中的 Sql 对象是 DateTime,refer this。 我可以通过使用一个函数从日期时间获取分钟来解决这个问题。但我通过为求和的日期时间获取 UNIXTIMESTAMP 的差异解决了这个问题。由于 UNIXTTIMESTAMP 总是 long 我可以将它转换为 Long 或 BigInteger
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。