本文介绍了当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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!