Sql server SQL Server 2016 DB中datetime列存在Hibernate JTDS/MSSQL JDBC驱动程序问题

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执行的同一个查询,就会

我们最近从SQLServer2008升级到SQLServer2016,一个特定的Hibernate/JPA错误进入了我们的视野,现在让我们非常头疼

我们使用Java和Hibernate(JPA2.1)来与DB进行接口

问题如下:

我们有一个表,其中的列类型为datetime。在Java程序结束时,我们通过hibernate执行一个命名更新查询,其中where子句中的这一列有一个条件:

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);
        }

    }
}