When UserType represents Set of Objects in single line. How to query Hibernate custom UserType with like criteria?

五迷三道 提交于 2019-12-08 14:06:59

问题


We are using custom Hibernate UserType to store a Set of Strings in a single line.

When trying to Query this set with like criteria, using JPA CriteriaBuilder Hibernate throws IllegalArgumentException

Parameter value String did not match expected type java.util.Set

Is there a workaround for this?

Here is a UserType we are using:

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:


From 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

So your line is not correct because you are setting a String not a Set as it's expected

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


来源:https://stackoverflow.com/questions/16381765/when-usertype-represents-set-of-objects-in-single-line-how-to-query-hibernate-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!