Stefano Cazzola
Stefano Cazzola

Reputation: 1687

Query filtering a collection using spring specifications

I have an entity A (ManyToMany, direct, lazy) which holds a reference to a collection of entities B.

I need to query the DB, searching for entities A based on the elements of class B it references. How can I do that with Spring specifications?

Upvotes: 0

Views: 4447

Answers (1)

Rafik BELDI
Rafik BELDI

Reputation: 4158

Well you can do it this way :

@Entity
public class A{

@ManyToMany
@JoinTable(....)
private Set<B> bs;
// getters and Setters

}

Class B , let's suppose you want to query by comparing a b.property

@Entity
public class B{
@Column
private String property;
// getters and setters 
}

An Abstract Class to provide the Specifications :

public abstract class ASpecifications{
    public static Specification<A> findByProperty(final String prop) {
        return new Specification<A>() {

            @Override
            public Predicate toPredicate(Root<A> root,
                    CriteriaQuery<?> arg1, CriteriaBuilder cb) {
                return cb.equal(root.join(A_.bs).get(B_.property), prop);
            }
        };
    }
}

Now use it @ the service layer this way :

import static package.ASpecifications.*;
import static org.springframework.data.jpa.domain.Specifications.where;

@Transactional(...)
public List<A> findByJoinPropertyOFB(String prop){
Specifications<A> spec = where(findByProperty(prop));
retrun repository.findAll(spec);
}

Now make sure that your Repository extends JpaSpecificationExecutor<A>

If B Contains a reference To another Object C and you want to compare throw a value of C

the spec can be extended this way :

cb.equal(root.join(A_.bs).get(B_c).get(c_.property), prop);

B_ , C_ And A_ are MetaModels of your entities. Hope this will help.

Upvotes: 7

Related Questions