本文介绍了当UserType表示单行对象集时。如何用类似条件查询Hibernate自定义的UserType?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



当试图用查询这个集合就像一样,条件,使用 JPA CriteriaBuilder Hibernate抛出 IllegalArgumentException
$ b

参数值字符串与预期类型不匹配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};

$ b @Override
public Object nullSafeGet(ResultSet rs,String [] names,SessionImplementor session,Object owner)throws HibernateException,
SQLException {
的HashSet<字符串> resultValues = new HashSet< String>();

字符串值= rs.getString(names [0]);
if(value == null)
return resultValues;

String [] values = value.split(SEPARATOR_REGEXP);
resultValues.addAll(Arrays.asList(values));
返回resultValues;

$ b @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));

$ b @Override
@SuppressWarnings(rawtypes)
public Class returnedClass(){
return Set.class;

$ b @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();

$ b @覆盖
@SuppressWarnings(unchecked)
public Object deepCopy(Object value)抛出HibernateException {
if(value == null )
返回null; $(bash)
if(value of instance of HashSet)
return((HashSet< String>)value).clone();

返回新的HashSet< String>((Collection< String>)value);
}

@Override
public boolean isMutable(){
return true;

$ b @Override
public可串行化反汇编(Object value)抛出HibernateException {
return(Serializable)deepCopy(value);

$ b @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;

$ b @Override
public String objectToSQLString(Set< String> value,Dialect dialect)throws Exception {
return StringUtils.collectionToDelimitedString(value,SEPARATOR);



$ div $解析方案

spring javadoc

  collectionToDelimitedString 

public static String collectionToDelimitedString(Collection coll,
String delim)

便捷方法将Collection作为分隔符(例如CSV)字符串返回。例如。用于toString()实现。

参数:
coll - 要显示的集合
delim - 要使用的分隔符(可能是,)
返回:
分隔字符串

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

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


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);
}
}
解决方案

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));

这篇关于当UserType表示单行对象集时。如何用类似条件查询Hibernate自定义的UserType?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-10 23:46