I have two entities:
AEntity:
@Entity
@Data
public class AEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
BEntity:
@Entity
@Data
public class BEntity{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToMany(fetch = FetchType.EAGER)
private List<AEntity> aEntities = new LinkedList();
}
I wanna load all BEntities from database by aEntities
containing List of AEntity's names using criteria API.
Example:
Database:
AEntities -> {1, "A1"}, {2, "A2"}, {3, "A3"}
BEntities -> {1, AEntities: {1, 2, 3}}, {2, AEntities: {1, 3}}, {3, AEntities: {3}}
If I call mySearchMethod(List.of("A1", "A3"))
it should return:
{1, AEntities: {1, 2, 3}}, {2, AEntities: {1, 3}}
because only these BEntities contains AEntities with names "A1" and "A3"
Tried to implement this with in
expression, but it cant find list in list :(
CodePudding user response:
I haven't tried this, but it might work this way:
public List<BEntity> mySearchMethod(List<String> keyList){
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<BEntity> cq = cb.createQuery(BEntity.class);
Root<BEntity> r = cq.from(BEntity.class);
cq.select(r);
ArrayList<Predicate> predicates = new ArrayList<>();
for(String key : keyList) {
predicates.add(cb.isMember(key, r.get(BEntity_.aEntities)));
}
if(predicates.size() > 0) {
if(predicates.size() == 1) {
cq.where(predicates.get(0));
}else {
cq.where(cb.and(predicates.toArray(new Predicate[predicates.size()])));
}
}
TypedQuery<BEntity> query = em.createQuery(cq);
return query.getResultList();
}