我正在尝试将休眠与 ms sql server 一起使用,并且难以将 sql 类型 datetimeoffset 映射到 java。如果我尝试在逆向工程配置中设置映射类型:
我收到一条错误消息。像 org.hibernate.MappingException: jdbc-type: microsoft.sql.Types.DATETIMEOFFSET 不是已知的 JDBC 类型也不是有效数字
我想在这种情况下只能使用 detault jdbc 类型。
关于如何解决这个问题的任何想法?
我正在尝试将休眠与 ms sql server 一起使用,并且难以将 sql 类型 datetimeoffset 映射到 java。如果我尝试在逆向工程配置中设置映射类型:
我收到一条错误消息。像 org.hibernate.MappingException: jdbc-type: microsoft.sql.Types.DATETIMEOFFSET 不是已知的 JDBC 类型也不是有效数字
我想在这种情况下只能使用 detault jdbc 类型。
关于如何解决这个问题的任何想法?
您可以提供自定义 Hibernate 用户类型。例如通过实现 org.hibernate.type.MutableType。
有关更多信息,请参阅Hibernate 参考。
An example custom type implementation for DatetimeOffset type can be seen below, on top of this you need to set the sql-type directive in the reverse engineering configuration file accordingly.
<type-mapping>
<sql-type jdbc-type="-155" hibernate-type="package.x.y.z.DatetimeOffsetType"></sql-type>
</type-mapping>
The jdbc-type= -155 is for ms sql server datetimeoffset type.
An example implementation:
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();
}
}