如何在 JPQL 中将日期时间转换为日期?

sho*_*von 1 sql spring jpa

这段代码有什么问题?

@Query(value = "Select " +
    "date(ivd.trnDatetime) as date, " +
    "ivd.binNo as bin, " +
    "ivd.snNo as sn, " +
    "count(ivd.invoiceNo) as totInvoice, " +
    "sum(ivd.totSaleAmt) as totSaleAmt " +
    "from InvoiceData ivd where ivd.status = 1 group by date(ivd.trnDatetime), ivd.binNo, ivd.snNo")
List<Object[]> getDailyTransactionReport();
Run Code Online (Sandbox Code Playgroud)

它抛出

    java.lang.IllegalArgumentException: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.MethodNode 
 +-[METHOD_CALL] MethodNode: '('
 |  +-[METHOD_NAME] IdentNode: 'date' {originalText=date}
 |  \-[EXPR_LIST] SqlNode: 'exprList'
 |     \-[DOT] DotNode: 'invoicedat0_.transaction_at' {propertyName=trnDatetime,dereferenceType=PRIMITIVE,getPropertyPath=trnDatetime,path=ivd.trnDatetime,tableAlias=invoicedat0_,className=com.efdms.transactionmonitoring.domain.InvoiceData,classAlias=ivd}
 |        +-[ALIAS_REF] IdentNode: 'invoicedat0_.id' {alias=ivd, className=com.efdms.transactionmonitoring.domain.InvoiceData, tableAlias=invoicedat0_}
 |        \-[IDENT] IdentNode: 'trnDatetime' {originalText=trnDatetime}
 [Select date(ivd.trnDatetime) as date, ivd.binNo as bin, ivd.snNo as sn, count(ivd.invoiceNo) as totInvoice, sum(ivd.totSaleAmt) as totSaleAmt from com.efdms.transactionmonitoring.domain.InvoiceData ivd where ivd.status = 1 group by date(ivd.trnDatetime), ivd.binNo, ivd.snNo]
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:138)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181)
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188)
    at org.hibernate.internal.AbstractSharedSessionContract.createQuery(AbstractSharedSessionContract.java:729)
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.orm.jpa.ExtendedEntityManagerCreator$ExtendedEntityManagerInvocationHandler.invoke(ExtendedEntityManagerCreator.java:351)
    at com.sun.proxy.$Proxy190.createQuery(Unknown Source)
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87)
    ... 62 common frames omitted
Run Code Online (Sandbox Code Playgroud)

trnDatetime实体中的属性

@NotNull
@Column(name = "transaction_at", nullable = false)
private Instant trnDatetime;
Run Code Online (Sandbox Code Playgroud)

SqlServer 中的等效列是 datetime

Ken*_*han 5

JPQL 不支持date(),因此您的查询失败。您有以下选择:

  1. 更改设置使用本地SQLnativeQuery=true@Query
  2. 如果您在使用Hibernate,使用HQL具体cast()是投trnDatetimeLocalDate
select cast(ivd.trnDatetime as LocalDate) as date ,
       count(ivd.invoiceNo) as totInvoice 
       from InvoiceData ivd 
       where ivd.status = 1 
       group by cast(ivd.trnDatetime as LocalDate)"
Run Code Online (Sandbox Code Playgroud)

为简洁起见,我忽略了其他列

请注意,结果列表的每一项中的索引 0 是一个 LocalDate


Laj*_*pad 1

错误消息告诉您 没有值transaction_at。这意味着表中的某些记录具有nulltransaction_at,或者由于某种原因查询未选择该记录。您需要确保select它,如果是的话,null您将拥有它的默认值,或者过滤掉具有null该特定字段值的记录。

transaction_at另外,如果不一定需要 的值,那么您可以nullable = false从 中删除@Column

编辑

正如评论部分指出的,解决方案是CAST(ivd.trnDatetime AS date)