java - JPA truncates nanoseconds when using date criteria & SQL datetime2 -
i'm trying create clause involving sql server datetime2 field (accurate 100 nanoseconds); using jpa & hibernate.
my code looks this:
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 reveals timestamp parameter value truncated 2015-06-04 11:31:53.210
- weird, that's not rounding. needles say, have inaccuracies in result set.
if manually change param full value 2015-06-04 11:31:53.2119339
good.
question is, how jpa not truncate date?
alternatively, how inject own parameter value serializer timestamp fields?
help appreciated;
update i've tracked jtds jdbc code: 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(); } }
where timestamp forced net.sourceforge.jtds.jdbc.datetime
type, supports milliseconds only.
this more of workaround; did make problem go away:
as stated in question update, jtds drivers not support datetime2 parameters. shifted microsoft drivers - problem solved.
some further workaround ideas:
- embed convert() function call, wrapping parameter literal; send timestamp string value.
- fix jtds code - jdbc supports nanos
Comments
Post a Comment