2015-06-04 37 views
1

我試圖創建一個涉及SQL Server datetime2字段(精確到100納秒)的where子句;使用JPA &休眠。當使用日期條件和SQL datetime2時,JPA截短納秒(秒)

我的代碼看起來是這樣的:

CriteriaBuilder cb = em.getCriteriaBuilder(); 
List<Predicate> predicates = new ArrayList<>(); 
CriteriaQuery(X) q = cb.createQuery(X.class); 
Root<X> root = q.from(X.class); 

java.sql.Timestamp mySqlTimeStamp = Timestamp.valueOf("2015-06-04 11:31:53.2119339"); 

predicates.add(cb.greaterThan(root.get("DateModified"), mySqlTimeStamp)) 

q.where(predicates.toArray(new Predicate[predicates.size()])); 

em.createQuery(q).getResultList(); 

SQL Server事件探查揭示了時間戳參數值被截斷爲2015-06-04 11:31:53.210 - 奇怪,這甚至不是一個舍入。針說,我在結果集中有不準確之處。

如果我手動將參數更改爲完整值2015-06-04 11:31:53.2119339一切都很好。

問題是,如何讓JPA到不是截斷日期?

或者,如何爲我的時間戳字段注入我自己的參數值序列化程序?

幫助讚賞;感謝

UPDATE 我就跟蹤到這個JTDS JDBC代碼: net.sourceforge.jtds.jdbc.JtdsPerparedStatement

protected void setParameter(int parameterIndex, Object x, int targetSqlType, int scale, int length) 
     throws SQLException { 
     ParamInfo pi = getParameter(parameterIndex); 

     if ("ERROR".equals(Support.getJdbcTypeName(targetSqlType))) { 
      throw new SQLException(Messages.get("error.generic.badtype", 
           Integer.toString(targetSqlType)), "HY092"); 
     } 

     // Update parameter descriptor 
     if (targetSqlType == java.sql.Types.DECIMAL 
      || targetSqlType == java.sql.Types.NUMERIC) { 

      pi.precision = connection.getMaxPrecision(); 
      if (x instanceof BigDecimal) { 
       x = Support.normalizeBigDecimal((BigDecimal) x, pi.precision); 
       pi.scale = ((BigDecimal) x).scale(); 
      } else { 
       pi.scale = (scale < 0) ? TdsData.DEFAULT_SCALE : scale; 
      } 
     } else { 
      pi.scale = (scale < 0) ? 0 : scale; 
     } 

     if (x instanceof String) { 
      pi.length = ((String) x).length(); 
     } else if (x instanceof byte[]) { 
      pi.length = ((byte[]) x).length; 
     } else { 
      pi.length = length; 
     } 

     if (x instanceof Date) { 
      x = new DateTime((Date) x); 
     } else if (x instanceof Time) { 
      x = new DateTime((Time) x); 
     } else if (x instanceof Timestamp) { 
      x = new DateTime((Timestamp) x); 
     } 

     pi.value = x; 
     pi.jdbcType = targetSqlType; 
     pi.isSet = true; 
     pi.isUnicode = connection.getUseUnicode(); 
    } 
} 

凡時間戳被迫net.sourceforge.jtds.jdbc.DateTime類型,只支持毫秒。

+0

我猜你的意思,而不是新的 「Timestamp.valueOf(......)」。我使用H2數據庫和DataNucleus JPA做了類似的事情,我的nanos被傳遞到數據存儲區。也許看看Hibernate在日誌中放入了什麼以及SQLServer JDBC驅動程序在做什麼? –

+0

是的,valueOf() - 我更正了代碼。我沒有通過nanos,但有更新等 - 但我正在使用JPA成功讀取它們。標準中的參數成功了嗎? – Gilbert

+0

你的意思是,在上面的標準中,只需放置一個cb.parameter,然後在查詢上調用setParameter(而不是使用文字)?是的,H2 + DataNucleus爲我工作 –

回答

0

這是更多的解決方法;它是我所做的,使問題消失:

正如問題更新中所述,它是不支持datetime2參數的jtds驅動程序。我只是轉向微軟的驅動程序 - 問題解決了。

一些進一步的解決方法的想法:

  • 嵌入一個轉換()函數調用,包裝參數的文字;發送Timestamp字符串值。
  • 修復JTDS碼 - 顯然JDBC支持NANOS