我们使用自定义 Hibernate UserType 在一行中存储一组字符串。
当尝试使用类似条件查询此集合时,使用JPA CriteriaBuilder Hibernate 会抛出IllegalArgumentException
Parameter value String did not match expected type java.util.Set
有解决方法吗?
这是我们正在使用的 UserType:
public class SetStringType implements UserType, LiteralType<Set<String>> {
final private static String SEPARATOR = "|";
final private static String SEPARATOR_REGEXP = "\\|";
@Override
public int[] sqlTypes() {
return new int[] { Types.VARCHAR };
}
@Override
public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner) throws HibernateException,
SQLException {
HashSet<String> resultValues = new HashSet<String>();
String value = rs.getString(names[0]);
if (value == null)
return resultValues;
String[] values = value.split(SEPARATOR_REGEXP);
resultValues.addAll(Arrays.asList(values));
return resultValues;
}
@Override
@SuppressWarnings("unchecked")
public void nullSafeSet(PreparedStatement st, Object value, int index, SessionImplementor session) throws HibernateException,
SQLException {
st.setString(index, StringUtils.collectionToDelimitedString((Collection<String>) value, SEPARATOR));
}
@Override
@SuppressWarnings("rawtypes")
public Class returnedClass() {
return Set.class;
}
@Override
public boolean equals(Object x, Object y) throws HibernateException {
return ObjectUtils.equals(x, y);
}
@Override
public int hashCode(Object x) throws HibernateException {
assert x != null;
return x.hashCode();
}
@Override
@SuppressWarnings("unchecked")
public Object deepCopy(Object value) throws HibernateException {
if (value == null)
return null;
if (value instanceof HashSet)
return ((HashSet<String>) value).clone();
return new HashSet<String>((Collection<String>) value);
}
@Override
public boolean isMutable() {
return true;
}
@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) deepCopy(value);
}
@Override
public Object assemble(Serializable cached, Object owner) throws HibernateException {
return deepCopy(cached);
}
@Override
public Object replace(Object original, Object target, Object owner) throws HibernateException {
return original;
}
@Override
public String objectToSQLString(Set<String> value, Dialect dialect) throws Exception {
return StringUtils.collectionToDelimitedString(value, SEPARATOR);
}
}