Question

I do have a static metamodel with a NUMBER (actually, BigDecimal, don't ask why) column. Now I would like to do a LIKE query against that number column:

CriteriaBuilder cb;
cb.like(entity.get(Entity_.numbercol), "123%");

where entity.get(Entity_.numbercol) returns a Path<BigDecimal>. Naturally, I get a compile error: ...like(Expression<String>, ...) ... not applicable for the arguments (Path<BigDecimal>, ...)

Casting the column with .as(String.class) fails due to some Bug in JPA, but I don't have the bug number at hands right now. It is not fixed in the latest version of JPA/Hibernate, though. Anyway, it results in a runtime exception about some invalid SQL statement being generated.

Now I just need a way to get the criteria API equivalent of the SQL

... WHERE numbercol LIKE '123%';

Searching for the topic already brought up the following responses, which don't help because I have a static metamodel: NHibernate - easiest way to do a LIKE search against an integer column with Criteria API? and JPA/Criteria API - Like & equal problem

Any ideas?

Thanks in advance Dominik

Was it helpful?

Solution

No, it does not fail because of bug, it works as specified (for example in Javadoc):

Perform a typecast upon the expression, returning a new expression object. This method does not cause type conversion: the runtime type is not changed. Warning: may result in a runtime failure.

Method you use performs cast and you need conversion. In general there is no support to convert from BigDecimal to String in JPA.

OTHER TIPS

For the people, who are still looking for a solution.

Knowing that HQLstr function does the job (at least for Hibernate v. 3.6.9.Final) one can implement his own FunctionExpression like:

//plagiarized from org.hibernate.ejb.criteria.expression.function.CastFunction
public class StrFunction<Y extends Number> extends BasicFunctionExpression<String> implements FunctionExpression<String>, Serializable {
    public static final String FCT_NAME = "str";

    private final Selection<Y> selection;

    public StrFunction(CriteriaBuilder criteriaBuilder, Selection<Y> selection) {
        super((CriteriaBuilderImpl) criteriaBuilder, String.class, FCT_NAME);
        this.selection = selection;
    }

    @Override
    public void registerParameters(ParameterRegistry registry) {
        Helper.possibleParameter(selection, registry);
    }

    @Override
    public String render(CriteriaQueryCompiler.RenderingContext renderingContext) {
        return FCT_NAME + '(' + ((Renderable) selection).render(renderingContext) + ')';
    }
}

and then use it:

cb.like(new StrFunction<Long> (cb, root.get(MyObject_.id)), "%mySearchTerm%");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top