1

SQL Server の datetime2 フィールド (100 ナノ秒までの精度) を含む where 句を作成しようとしています。JPAとHibernateを使用。

私のコードは次のようになります。

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 が日付を切り捨てないようにする方法です。

または、タイムスタンプ フィールドに独自のパラメーター値シリアライザーを挿入する方法を教えてください。

助けていただければ幸いです。ありがとう

更新 私はこの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ミリ秒のみをサポートするタイムスタンプの入力が強制されます。

4

1 に答える 1

0

これは回避策です。問題を解決するために私がしたこと:

質問の更新で述べたように、datetime2 パラメーターをサポートしていないのは jtds ドライバーでした。Microsoft ドライバーに移行しただけで、問題は解決しました。

さらなる回避策のアイデア:

  • Convert() 関数呼び出しを埋め込み、パラメーター リテラルをラップします。Timestamp 文字列値を送信します。
  • jtds コードを修正 - 明らかに jdbc が nanos をサポート
于 2015-06-12T04:22:35.810 に答える