我定义了一个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)]

我尝试实现LiteralTypeobjectToSQLString方法,但它看起来不像这个方法。

作为简化示例:

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

#1楼 票数:3 已采纳

我想你需要改变返回的类:

@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

返回类ClassClass

nullSafeGet()返回的类。 返回:类

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

#2楼 票数:1

使用Spring Data,您可以实现自定义查询实现,并且可以将EntityManager到Hibernate会话,然后将您创建的自定义类型提供给查询:

@PersistenceContext
private EntityManager entityManager;

public List<BlahBlah> findTransformed(String text) {
    Session session = entityManager.unwrap(Session.class);

    TypeHelper typeHelper = session.getSessionFactory().getTypeHelper();

    List<BlahBlah> result = (List<BlahBlah>) session.createQuery(
        "select b " +
        "from BlahBlah b " +
        "where b.transformed = :transformed ")
    .setParameter("transformed", text, typeHelper.custom(MyUserType.class))
    .list();
}  

  ask by Chris Williams translate from so

未解决问题?本站智能推荐:

1回复

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

我们正在使用自定义的Hibernate UserType在一行中存储一组字符串。 尝试使用类似条件查询此集合时,使用JPA CriteriaBuilder Hibernate抛出IllegalArgumentException Parameter value String did no
2回复

如何使用usertype在JPA中使用Hibernate持久保存JSR 310 java.time.LocalDateTime

我正在尝试使用usertype在Java中使用Hibernate在Java 8中持久保存java.time.LocalDateTime。 我有一个注释如下的财产。 我已经为usertype添加了依赖项,如下所示。 但是,我有以下例外情况 stacktrace暗示Cl
1回复

Hibernate-NamedSqlQuery用户类型作为ReturnType

我在Hibernate中有一个映射的类,其中包含一个名为sql-query的查询,该查询计算某些搜索参数的整数最小值。 实际的查询非常复杂(因此我既不能将其编写为Criteria,也无法在Hibernate版本中将其编写为HQL)。 数据库中的返回类型是整数,但是我有一个将该整数映射到日
2回复

java.lang.AbstractMethodError: 在 UserType.nullSafeSet()

我有自定义的enum值要保存在数据库中。 为此,我实现了StringValuedEnum 、 StringValuedEnumType和StingValuedEnumReflect并且我的enum实现了StringValuedEnum 。 当我使用手动管理的 JPA 运行我的代码时,一切正常,并且
1回复

如何在Hibernate 4.x中使用JodaTime Instant(时间戳)(通过Jadira usertype)?

我在Postgres中有一个timestamp(0) without time zone列的timestamp(0) without time zone ,并希望通过Hibernate 4.2.2将其映射到Joda-Time Instant。 Joda-Time站点引用了Hibernate版本
3回复

使用Hibernate执行“IN”查询

我在String中有一个ID列表,并希望使用Hibernate来获取具有这些ID的行。 TrackedItem是一个Hibernate / JPA实体(对不起,如果我在这里混淆命名)。 我的代码是: 但是失败了: JPAQueryException occured : Error
2回复

Hibernate:在子选择查询中使用IN子句时出现严重错误

使用休眠4.3.11.final。 我们使用@Query注释发出请求,在子选择查询ex中使用in子句: 第一个in子句正确生成(添加了括号),但subselect中的子句不是。 生成的sql是: 解决方法是在声明的查询中将圆括号的一部分括起来: 有没有更好的方
3回复

Hibernate / JPA / HSQL:如何为用户类型ARRAY创建方言映射

我已经使用Postgres成功创建了用户类型,并且可以成功读写。 但是,当我尝试使用HSQLDialect(用于单元测试)时,我得到: 2003是java.sql.Types.Array似乎在尝试在测试之前创建架构时失败,并且我不确定如何告诉HSQL创建正确的类型/架构。