rdonovan
rdonovan

Reputation: 21

Using Soundex and CriteriaBuilder API from EclipseLink

Currently in the process of creating a object search using CriteriaBuilder, Predicates, JPA 2.0 with EclipseLink as provider.

My challenge is accessing the soundex capabilities and applying it to a dynamically built criteria.

    CriteriaBuilder cb = PersistenceUtil.getEntityManager().getCriteriaBuilder();
    CriteriaQuery<Registration> q = cb.createQuery(Registration.class);
    Root<Registration> dr = q.from(Registration.class);

    List<Predicate> predicates = new ArrayList<Predicate>();

... Loop of my inputs to the query

    predicates.add(cb.equal(dr.get(fieldName),fieldValue));

... and finally

    q.select(dr).where(predicates.toArray(new Predicate[]{}));

    TypedQuery<Registration> query = PersistenceUtil.getEntityManager().createQuery(q).setMaxResults(maxResults);

    List<DeathRegistration> results = query.getResultList();

This obviously works fine for the simple criteria builder items, and I can use 'like', 'greaterThan', date comparison and so on.

I want to enable use of a Expression that uses the EclipseLink soundex() operator. Using EclipseLink provider opens up my ability to create an eclipselink Expression, but I canot figure out how to apply it to a predicate.

                        ReadAllQuery raq = new ReadAllQuery(Registration.class);        
                        ExpressionBuilder eb = raq.getExpressionBuilder();
                        org.eclipse.persistence.expressions.Expression fnExp = ExpressionOperator.soundex().expressionFor(eb.get(fieldName));
                        org.eclipse.persistence.expressions.Expression fnVal = fnExp.equal(fieldValue);

Having a lot of trouble finding documentation that would allow me to create an Expression that can be used in CriteriaBuilder. Is it possible? Can an EclipseLink Expression be converted to a parametrized persistence Expression<>? ... and then be set as a predicate for the built criteria query?

Upvotes: 0

Views: 1148

Answers (1)

rdonovan
rdonovan

Reputation: 21

After sleeping on the issue, and some more googling. Here is where I ended up:

    Expression<String> exp = dr.get(fieldName);
    Expression<String> expName = CriteriaBuilderHelper.functionSoundexName(cb, exp);
    Expression<String> expValue = CriteriaBuilderHelper.functionSoundexValue(cb, fieldValue);                               
    predicates.add(cb.equal(expName, expValue));

and my function:

private static final String SOUNDEX = "soundex";
/**
* @param cb the CriteriaBuilder to use
* @param value the value to soundex
* @return Expression<String>
*/

public static Expression<String> functionSoundexName(CriteriaBuilder cb, Expression<String> exp) {
    return cb.function(
        SOUNDEX,
        String.class,
        cb.lower(exp)
    );
}   

public static Expression<String> functionSoundexValue(CriteriaBuilder cb, String value) {
    return cb.function(
        SOUNDEX,
        String.class,
        cb.lower(cb.literal(value))
    );
}

Upvotes: 2

Related Questions