I am an unfortunate dev that needs to work with a very legacy database. The problem is, that the database contains custom datatypes:
CREATE DISTINCT TYPE SCHEMA.T_STUPID_ID AS
SMALLINT WITH COMPARISONS
;
So I cannot change that, but need to get the data and query it. It appears that it does not work, cause when querying by Id (findOne) using spring data jpa (repository) I get the following error:
DB2 SQL Error: SQLCODE=-401, SQLSTATE=42818, SQLERRMC==, DRIVER=4.19.26
which is : THE DATA TYPES OF THE OPERANDS OF AN OPERATION ARE NOT COMPATIBLE So it sounds like the queries do not work with custom types :/
I also tried this way:
@Query("select p from ImSickOfThisEntity p where cast(p.entityId as integer)
= ?1 ")
But I got:
DB2 SQL Error: SQLCODE=-461, SQLSTATE=42846, SQLERRMC=IPSDBO.T_PRODUCT_ID;SYSIBM.INTEGER
which translates to :
A VALUE WITH DATA TYPE source-data-type CANNOT BE CAST TO TYPE target-data-type
How to deal with such custom types? Google is not helpful, I can only find custom Java types with standard database column types....
You'll need to implement a UserType and you can specify the sqlTypes.
public class SmallIntHibernateType implements UserType {
@Override
public int[] sqlTypes() {
return new int[] {Types.SMALLINT};
}
@Override
public Class returnedClass() {
return Integer.class;
}
@Override
public boolean equals(Object o, Object o2) throws HibernateException {
if (o == null && o2 == null) {
return true;
} else if (o == null) {
return false;
} else if (o2 == null) {
return false;
} else {
return ((Integer) o).intValue() == ((Integer) o2).intValue();
}
}
@Override
public int hashCode(Object o) throws HibernateException {
return o.hashCode();
}
@Override
public Object nullSafeGet(ResultSet resultSet, String[] strings, SharedSessionContractImplementor sessionImplementor, Object o) throws HibernateException, SQLException {
return resultSet.getInt(strings[0]);
}
@Override
public void nullSafeSet(PreparedStatement preparedStatement, Object value, int index, SharedSessionContractImplementor sessionImplementor) throws HibernateException, SQLException {
if (value == null || value.equals(0)) {
preparedStatement.setNull(index, Types.INTEGER);
return;
}
if (!(value instanceof Integer)) {
throw new UnsupportedOperationException("can't convert " + value.getClass());
}
preparedStatement.setInt(index, ((Integer) value));
}
@Override
public Object deepCopy(Object value) throws HibernateException {
if (value == null) {
return null;
}
if (!(value instanceof Integer)) {
throw new UnsupportedOperationException("can't convert " + value.getClass());
}
return value;
}
@Override
public boolean isMutable() {
return false;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
if (!(value instanceof Integer)) {
throw new UnsupportedOperationException("can't convert " + value.getClass());
}
return (Integer) value;
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
if (!(cached instanceof Integer)) {
throw new UnsupportedOperationException("can't convert " + cached.getClass());
}
return cached;
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
}
Then on your entity you'll need to specify the using the type.
@Id
@Type(type = "com.data.system.SmallIntHibernateType")
private int id;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.