Reputation: 21
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
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