当UserType表示单行中的对象集时。如何使用类似标准查询Hibernate自定义UserType?

时间:2013-05-05 05:43:01

标签: java hibernate orm usertype

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

1 个答案:

答案 0 :(得分:0)

来自spring 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

所以你的行不正确,因为你设置的字符串不是预期的

st.setString(index, StringUtils.collectionToDelimitedString((Collection<String>) value, SEPARATOR));