加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – Hibernate – 不能在where子句中使用UserType执行查询

发布时间:2020-12-14 05:14:39 所属栏目:Java 来源:网络整理
导读:我有一个Hibernate UserType被定义为在数据进入我们的数据库之前转换数据,然后在从数据库读回数据时将其解压缩.当插入行或使用行的ID或其他方式查询行时,这样做很好.但是,当我尝试使用查询来查找记录时,参数绑定似乎失败: org.springframework.dao.InvalidD
我有一个Hibernate UserType被定义为在数据进入我们的数据库之前转换数据,然后在从数据库读回数据时将其解压缩.当插入行或使用行的ID或其他方式查询行时,这样做很好.但是,当我尝试使用查询来查找记录时,参数绑定似乎失败:
org.springframework.dao.InvalidDataAccessApiUsageException: Parameter value [thisIsTheSearchString] did not match expected type [com.xxx.MyUserType (n/a)]; nested exception is java.lang.IllegalArgumentException: Parameter value [thisIsTheSearchString] did not match expected type [com.xxx.MyUserType (n/a)]

我尝试实现LiteralType和objectToSQLString方法,但它看起来不像这样的方法被调用.

作为一个简化的例子:

public class MyUserType implements UserType,LiteralType {

    @Override
    public int[] sqlTypes() {
        return new int[] {
                Types.VARCHAR
        };
    }

    @Override
    public Class returnedClass() {
        return MyUserType.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
    public Object nullSafeGet(
            ResultSet rs,String[] names,SessionImplementor session,Object owner) 
                    throws HibernateException,SQLException
    {
        assert names.length == 1;
        return untransform( rs.getString( names[0] ); );
    }

    String transform(String untransformed) {
        //...
    }

    String untransform(String transformed) {
        //...
    }

    @Override
    public void nullSafeSet(
            PreparedStatement st,Object value,int index,SessionImplementor session)
                    throws HibernateException,SQLException 
    {
        if ( value == null ) {
            st.setNull(index,Types.VARCHAR);
        } else {
            final String untransformed = (String)value;

            return transform(untransformed);
        }
    }

    @Override
    public Object deepCopy(Object value) throws HibernateException {
        if ( value == null ) {
            return null;
        }
        return (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 deepCopy(original);
    }

    // THIS NEVER GETS CALLED
    @Override
    public String objectToSQLString(Object value,Dialect dialect)
            throws Exception 
    {
        if ( value == null ) {
            return null;
        }

        String transformed = transform((String)value);

        StringType stringType = new StringType();
        String sqlString = stringType.objectToSQLString(transformed,dialect);

        return sqlString;
    }
}

实体看起来像:

@Entity
@Table(name = "blah_blah")
@TypeDefs(value = { @TypeDef(name = "transformedText",typeClass = MyUserType.class)})
public class BlahBlah implements Serializable,Persistable<Long> {

    //...

    @Column(name = "transformed")
    @Type(type = "transformedText")
    String transformed;

    //...
}

我的查询:

@Query(value = 
        "select b " +
        "from BlahBlah b " +
        "where b.transformed = ?1 ")
public List<BlahBlah> findTransformed(String text);

解决方法

我想你需要改变返回的类:
@Override
public Class returnedClass() {
    return MyUserType.class;
}

应该:

@Override
public Class returnedClass() {
    return String.class;
}

在文档(https://docs.jboss.org/hibernate/orm/3.5/api/org/hibernate/usertype/UserType.html#returnedClass())中:

returnedClass

Class returnedClass()

The class returned by nullSafeGet().
Returns:
Class

并且您的nullSafeGet似乎返回一个String.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读