Skip to content
Advertisement

Predicate alternative in Kotlin

I try to create lambda in Kotlin. I has following Java interface:

public interface Specification<T> extends Serializable {
    @Nullable
    Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder builder);
}

And in Java I can return new Specification from method like:

private Specification<Product> nameLike(String name){
    return new Specification<Product>() {
        @Override
        public Predicate toPredicate(Root<Product> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
            return criteriaBuilder.like(root.get(Product_.NAME), "%"+name+"%");
        }
    };
}

And with Java 8 I can cut it to labda like:

private Specification<Product> nameLike(String name) {
    return (root, query, criteriaBuilder) 
        -> criteriaBuilder.like(root.get(Product_.NAME), "%"+name+"%");
}

How to do it in Kotlin with lamba? I already tried many options, but they do not compile. help please.

Update: Last option in Kotlin:

class ProductSpecification {
    fun nameLike(name: String): (Root<Product>, CriteriaQuery<Product>, CriteriaBuilder) -> Predicate = {
        root, query, builder -> builder.like(root.get("name"), "%$name%")
    }
}

It compiles, but when I pass it in function with argument Specification, I have error None of the following functions can be called with the arguments supplied.. Code example of invoking:

repository.findAll(ProductSpecification().nameLike("fff"))

Advertisement

Answer

I found solution! When I started to implement roughly option like of the second code example in my question, IDE suggests to do like:

fun nameLike(name: String) = Specification { root: Root<Product>, query: CriteriaQuery<*>, builder: CriteriaBuilder ->
    builder.like(root.get("name"), "%$name%")
}

That’s fine for me

Advertisement