1

我们使用自定义 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);
}
}
4

1 回答 1

0

从春天的javadoc

 collectionToDelimitedString

public static String collectionToDelimitedString(Collection coll,
                                             String delim)

 Convenience method to return a Collection as a delimited (e.g. CSV) String. E.g. useful for toString() implementations.

Parameters:
    coll - the Collection to display
    delim - the delimiter to use (probably a ",") 
Returns:
    the delimited String

因此,您的行不正确,因为您设置的是 String 而不是 Set ,因为它是预期的

st.setString(index, StringUtils.collectionToDelimitedString((Collection<String>) value, SEPARATOR));
于 2014-03-31T09:52:21.907 回答