shovon
shovon

Reputation: 111

How to convert datetime to date in JPQL?

What's the problem with this code?

@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();

It throws

    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

The property for trnDatetime in entity

@NotNull
@Column(name = "transaction_at", nullable = false)
private Instant trnDatetime;

and equivalent column in SqlServer is datetime

Upvotes: 9

Views: 20927

Answers (2)

Ken Chan
Ken Chan

Reputation: 90447

JPQL does not support date() and so your query fails.You have the following options :

  1. Change to use the native SQL by setting nativeQuery=true in @Query
  2. If you are using Hibernate , use the HQL specific cast() that cast trnDatetime to LocalDate :
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)"

I ignore other columns for the sake of brevity

Please note that the index 0 in each item of the result list is a LocalDate

Upvotes: 16

Lajos Arpad
Lajos Arpad

Reputation: 76508

The error message tells you that there is no value for transaction_at. This means that some records in your table have a null value for transaction_at or that it is not selected by the query for some reason. You will need to make sure that you select it and in case it is null you will either have a default value for it, or you filter out records which have null as a value for that particular field.

Also, if a value for transaction_at is not necessarily required, then you can remove nullable = false from the @Column.

EDIT

The solution, as pointed out in the comment section was CAST(ivd.trnDatetime AS date)

Upvotes: 1

Related Questions