簡體   English   中英

java.time.LocalDate 參數在休眠查詢中作為 java.util.Date 處理

[英]The java.time.LocalDate parameter processes as java.util.Date in hibernate query

我正在嘗試將java.time.LocalDate參數傳遞給命名查詢,但 Hibernate 錯誤地預期了java.util.Date類型的參數。 我在 Spring Boot 2.2.5(使用 Hibernate 5.4.12 和 JPA 2.2.5)上使用 Java 8。

例外:

    Exception - org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [2020-03-30] did not match expected type [java.util.Date (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [2020-03-30] did not match expected type [java.util.Date (n/a)]

DAO方法:

java.time.LocalDate date = LocalDate.now(); // example date
result = entityManager.createNamedQuery("MyTableEntity.query", MyTableEntity.class)
        .setParameter("date", date)
        .setMaxResults(1)
        .getSingleResult();

命名查詢:

@NamedQuery(name = "MyTableEntity.query", query = "SELECT o FROM MyTableEntity o WHERE date(o.timestamp) = :date")

實體:

@Entity
@Table(name = "my_table")
public class MyTableEntity implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id")
    private Long id;

    @Column(name = "time_control")
    private java.time.OffsetDateTime timestamp;

    private static final long serialVersionUID = 1L;

    // constructors...
    // getters and setters...
}

我認為問題(錯誤?)出在命名查詢中,其中從TimestampDate生成java.util.Data類型。 事實上,如果我在相同類型的屬性上使用LocalDate類型參數查詢另一個實體,它會按預期工作。

但是我通過傳遞java.sql.Date.valueOf(date)作為參數解決了這個問題,但我想知道為什么 Hibernate 沒有像我預期的那樣解析LocalDate

您在 hql/jpql 查詢中使用的每個函數都應該在您使用的休眠方言中聲明。 在您的情況下, date函數的聲明看起來像這樣:

import org.hibernate.type.StandardBasicTypes;

public YourDialect {

  // ...
  registerFunction( "date", new StandardSQLFunction( "date", StandardBasicTypes.DATE ) );

}

在下面你可以看到StandardBasicTypes.DATE是如何定義的:

/**
 * The standard Hibernate type for mapping {@link java.util.Date} ({@link java.sql.Date}) to JDBC
 * {@link java.sql.Types#DATE DATE}.
 *
 * @see TimeType
 */
public static final DateType DATE = DateType.INSTANCE;

這就是為什么你在你的問題例外中提到了。 您可以通過以下方式重新定義date函數來更改此設置:

import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.type.LocalDateType;

public class MyDialect extends SomeHibernateDialect
{
   public MyDialect()
   {
      super();
      registerFunction( "date", new StandardSQLFunction( "date", LocalDateType.INSTANCE ) );
   }
}

然后用這個方言。 之后,您的初始查詢將起作用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM