datetimeoffset 休眠映射

Posted

技术标签:

【中文标题】datetimeoffset 休眠映射【英文标题】:datetimeoffset hibernate mapping 【发布时间】:2011-06-11 15:43:32 【问题描述】:

我正在尝试将休眠与 ms sql server 一起使用,并且在将 sql 类型 datetimeoffset 映射到 java 时遇到了困难。 如果我尝试在逆向工程配置中设置映射类型:

我收到一条错误消息。喜欢 org.hibernate.MappingException: jdbc-type: microsoft.sql.Types.DATETIMEOFFSET 不是已知的 JDBC 类型也不是有效数字

我猜在这种情况下只能使用 detault jdbc 类型。

关于如何解决这个问题的任何想法?

【问题讨论】:

【参考方案1】:

您可以提供自定义的 Hibernate 用户类型。例如通过实现 org.hibernate.type.MutableType。

更多信息请参考Hibernate Reference。

【讨论】:

【参考方案2】:

DatetimeOffset 类型的自定义类型实现示例如下所示, 除此之外,您还需要在逆向工程配置文件中相应地设置 sql-type 指令。

<type-mapping>
 <sql-type jdbc-type="-155" hibernate-type="package.x.y.z.DatetimeOffsetType"></sql-type> 
 </type-mapping>

jdbc-type= -155 适用于 ms sql server datetimeoffset 类型。

一个示例实现:

public class DatetimeOffsetType  implements UserType  

static 
    initializeMethods();


private static Method methodSetDateTimeOffset;

@Override
public Object assemble(Serializable arg0, Object arg1)
        throws HibernateException 
    return arg0;


@Override
public Object deepCopy(Object value) throws HibernateException 
    DateTimeOffset dateTimeOffset = (DateTimeOffset)value;
    return (value == null) ? null :
        DateTimeOffset.valueOf(dateTimeOffset.getTimestamp(), dateTimeOffset.getMinutesOffset());


@Override
public Serializable disassemble(Object arg0) throws HibernateException 
    return (Serializable)arg0;


@Override
public boolean equals(Object arg0, Object arg1) throws HibernateException 
    if(arg0 == null || ! (arg0 instanceof DateTimeOffset) || arg1 == null || ! (arg1 instanceof DateTimeOffset)) 
        return false;
    

    return arg0.equals(arg1);


@Override
public int hashCode(Object arg0) throws HibernateException 
    return arg0.hashCode();


@Override
public boolean isMutable() 
    return true;


@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
        throws HibernateException, SQLException 
        return (DateTimeOffset) resultSet.getObject(names[0]);


@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index)
        throws HibernateException, SQLException 
    // TODO check casting
    if(preparedStatement instanceof SQLServerPreparedStatement) 
        SQLServerPreparedStatement  sqlServerPreparedStatement  = (SQLServerPreparedStatement)preparedStatement;
         sqlServerPreparedStatement.setDateTimeOffset(index, (DateTimeOffset) value);
    else 

         try 
             C3P0ProxyStatement proxyStatement = (C3P0ProxyStatement)preparedStatement;
             (proxyStatement).rawStatementOperation(methodSetDateTimeOffset,C3P0ProxyStatement.RAW_STATEMENT, new Object[] index,(DateTimeOffset) value);
         catch (Exception e) 

        

    


@Override
public Object replace(Object original, Object target, Object arg2)
        throws HibernateException 
    // TODO Auto-generated method stub
    System.out.println("replace");
    return null;


@Override
public Class<DateTimeOffset> returnedClass() 
    return DateTimeOffset.class;


@Override
public int[] sqlTypes() 
    return new int[] microsoft.sql.Types.DATETIMEOFFSET; //-155


private static void initializeMethods() 
    try 
        final Class c = Class.forName("com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement");
        methodSetDateTimeOffset = c.getMethod("setDateTimeOffset", new Class[] Integer.TYPE,DateTimeOffset.class);
     catch (Exception e) 
        // TODO: handle exception
        e.printStackTrace();
    

【讨论】:

以上是关于datetimeoffset 休眠映射的主要内容,如果未能解决你的问题,请参考以下文章

EF Core 仅查询 DateTimeOffset 的 DateTime 无法翻译;

实体框架将 DateTimeOffset 映射到 SQL Server DateTime

不存在从 DbType System.DateTimeOffset 到已知 SqlCeType 的映射

proxmox映射硬盘的休眠控制

休眠映射异常:实体映射中的重复列

格瑞斯 GORM。将映射添加到现有的休眠映射