2011-01-19 161 views
3

我想與ms sql服務器一起使用hibernate,並且難以將sql類型datetimeoffset映射到java。 如果我嘗試在逆向工程配置中設置映射類型: datetimeoffset休眠映射

我收到一個錯誤,說某事。像 org.hibernate.MappingException:jdbc-type:microsoft.sql.Types.DATETIMEOFFSET不是一個已知的JDBC類型也不是有效的數字

我猜想在此上下文中只能使用detault jdbc類型。

有關如何解決此問題的任何想法?

回答

2

您可以提供自定義的Hibernate用戶類型。例如通過實現org.hibernate.type.MutableType。

請參閱Hibernate Reference瞭解更多信息。

1

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