Reputation: 13
I am implementing search functionality in my application. I am using Specification in findAll()
and it is working perfectly. But when ever i am trying to achive in other methods like findByFirstName()
it is not working
I am including what i did so far.
AircraftSpecification.java
public class AircraftSpecification {
private AircraftSpecification() {}
public static Specification<Aircraft> textInAllColumns(String text) {
if (!text.contains("%")) {
text = "%"+text+"%";
}
final String finalText = text;
return new Specification<Aircraft>() {
private static final long serialVersionUID = 1L;
@Override
public Predicate toPredicate(Root<Aircraft> root, CriteriaQuery<?> cq, CriteriaBuilder builder) {
List<SingularAttribute<Aircraft, ?>> tempAttributes = new ArrayList<>();
for (SingularAttribute<Aircraft, ?> attribute : root.getModel().getDeclaredSingularAttributes()) {
if (attribute.getJavaType().getSimpleName().equalsIgnoreCase("string")) {
tempAttributes.add(attribute);
}
}
final Predicate[] predicates = new Predicate[tempAttributes.size()];
for (int i = 0; i < tempAttributes.size(); i++) {
predicates[i] = builder.like(builder.lower(root.get(tempAttributes.get(i).getName())), finalText.toLowerCase());
}
return builder.or(predicates);
}
};
}
}
When i am calling
aircraftRepository.findAll(Specification.where(AircraftSpecification.textInAllColumns(searchText)));
it giving me proper data.
But when i am calling
aircraftRepository.findAllByName(name, Specification.where(AircraftSpecification.textInAllColumns(searchText)));
It throwing Exception.
Exception Is:
org.springframework.dao.InvalidDataAccessApiUsageException: At least 2 parameter(s) provided but only 1 parameter(s) present in query.; nested exception is java.lang.IllegalArgumentException: At least 2 parameter(s) provided but only 1 parameter(s) present in query.
Can any one help me how to use Specification other than findAll method.
Upvotes: 0
Views: 1664
Reputation: 81907
You can't combine derived queries where Spring Data derives the query to execute from the method name with Specification
.
Just make the name part of a query a Specification
as well and combine the two with and.
The resulting call could look like this or similar:
aircraftRepository.findAll(
byName("Alfred")
.and(textInAllColumns(searchText))
);
Upvotes: 1