4

ms sql サーバーで hibernate を使用しようとしていますが、sql 型の datetimeoffset を Java にマッピングするのが困難です。リバース エンジニアリング構成でマッピング タイプを設定しようとすると、次のようになります。

sth というエラーが表示されます。org.hibernate.MappingException のように: jdbc-type: microsoft.sql.Types.DATETIMEOFFSET は既知の JDBC タイプでも有効な数値でもありません

このコンテキストでは、detault jdbc タイプのみを使用できると思います。

この問題を解決する方法についてのアイデアはありますか?

4

2 に答える 2

2

カスタムのHibernateユーザータイプを提供できます。たとえば、org.hibernate.type.MutableTypeを実装します。

詳細については、 Hibernateリファレンスを参照してください。

于 2011-01-19T10:06:50.877 に答える
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 サーバーの 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();
    }
}
于 2011-01-20T09:53:10.203 に答える