Sql server SQL Server 2016 DB中datetime列存在Hibernate JTDS/MSSQL JDBC驱动程序问题
我们最近从SQLServer2008升级到SQLServer2016,一个特定的Hibernate/JPA错误进入了我们的视野,现在让我们非常头疼 我们使用Java和Hibernate(JPA2.1)来与DB进行接口 问题如下: 我们有一个表,其中的列类型为datetime。在Java程序结束时,我们通过hibernate执行一个命名更新查询,其中where子句中的这一列有一个条件:Sql server SQL Server 2016 DB中datetime列存在Hibernate JTDS/MSSQL JDBC驱动程序问题,sql-server,hibernate,datetime,jtds,mssql-jdbc,Sql Server,Hibernate,Datetime,Jtds,Mssql Jdbc,我们最近从SQLServer2008升级到SQLServer2016,一个特定的Hibernate/JPA错误进入了我们的视野,现在让我们非常头疼 我们使用Java和Hibernate(JPA2.1)来与DB进行接口 问题如下: 我们有一个表,其中的列类型为datetime。在Java程序结束时,我们通过hibernate执行一个命名更新查询,其中where子句中的这一列有一个条件: datetime-column < :parameter. 如果我们查看使用JTD执行的同一个查询,就会
datetime-column < :parameter.
如果我们查看使用JTD执行的同一个查询,就会看到传递的是datetime参数,而不是datetime2
我现在的问题是:我们不想将datetime列更新为datetime2。是否有其他方法来配置hibernate,使其将日期参数作为datetime而不是datetime2发送到db
谁能给我们指出正确的方向吗?我尝试了一切,包括将数据类型更改为calendar、实现此处所述的自定义用户类型()、删除/更改时态注释,甚至尝试自定义SQL Server方言以强制传递datetime而不是datetime2
直到现在(或者我做错了)一切都不起作用,有什么建议吗
2018年1月25日更新:
更清楚地说,我尝试了以下方法:
public class CustomSQLServerDialect extends SQLServer2012Dialect {
public CustomSQLServerDialect() {
registerColumnType(Types.TIMESTAMP, "datetime");
}
}
以及定义这样的自定义用户类型(老实说,从具有类似问题的帖子粘贴的副本):
您找到使用纯JDBC的解决方案了吗 您是否尝试过以下方法: 准备好的报表 默认void setObject(int参数索引、对象x、SQLType targetSqlType)
可能存在特定于供应商的SQLType。感谢您的反馈,我将尝试使用JDBC实现查询,然后调试驱动程序以查看哪个SQLType有效。我调试了查询,它似乎是microsoft驱动程序的PreparedStatement.setTimestamp()方法中的数据转换问题。这里也讨论了这个问题:。尽管有人在20天前将工单分配到“下一个任务”里程碑,但目前没有可用的修复程序。似乎这个bug很新鲜:)
public class CustomSQLServerDialect extends SQLServer2012Dialect {
public CustomSQLServerDialect() {
registerColumnType(Types.TIMESTAMP, "datetime");
}
}
import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.Date;
import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;
public class DateTimeUserType implements UserType {
@Override
public int[] sqlTypes() {
return new int[] { Types.TIMESTAMP };
}
@SuppressWarnings("rawtypes")
@Override
public Class returnedClass() {
return Date.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return x == y || !(x == null || y == null) && x.equals(y);
}
@Override
public int hashCode(Object x) throws HibernateException {
return x.hashCode();
}
@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
throws HibernateException, SQLException {
Timestamp timestamp = rs.getTimestamp(names[0]);
if (rs.wasNull()) {
return null;
}
return new Date(timestamp.getTime());
}
@Override
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session)
throws HibernateException, SQLException {
if (value == null) {
st.setNull(index, Types.TIMESTAMP);
} else {
Date date = (Date) value;
Timestamp timestamp = new Timestamp(date.getTime());
st.setTimestamp(index, timestamp);
}
}
}