Я пытаюсь создать предложение where с использованием поля datetime2 SQL Server (с точностью до 100 наносекунд); используя JPA & Hibernate.JPA усекает наносекунды при использовании критериев даты и SQL datetime2
Мой код выглядит примерно так:
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 Profiler показывает значение параметра метка времени усекается до 2015-06-04 11:31:53.210
- странно, что даже не округление. Иглы сказать, у меня есть неточности в результирующем наборе.
Если я вручную изменю параметр на полное значение 2015-06-04 11:31:53.2119339
, все это хорошо.
Вопрос в том, как получить JPA до не усекать дату?
В качестве альтернативы, как вводить мое собственное значение сериализатора параметров для полей timestamp?
Справка оценена; благодаря
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
типа, который поддерживает только миллисекунду.
Я думаю, вы имеете в виду "Timestamp.valueOf (...)" вместо нового. Я сделал аналогичную вещь, используя базу данных H2 и DataNucleus JPA, и мои наносы передаются в хранилище данных. Возможно, посмотрите, что Hibernate помещает в журнал и что делает драйвер SQLServer JDBC? –
Да, valueOf() - Я скорректировал код. Я не передаю nanos, но обновляю и т. Д., Но я успешно их читаю, используя JPA. Получили ли вы успех с параметрами в критериях? – Gilbert
Вы имеете в виду, в критерии выше, просто поместите cb.parameter, а затем вызовите setParameter в запросе (вместо использования литерала)? Да, это сработало для меня с H2 + DataNucleus –