简体   繁体   中英

How to use Predicate with Collection

I have three tables.

  1. parent
  2. parent_child_mapping
  3. child

I want to filter by child name using predicate. I am trying this without passing child name as argument. I want to return the Parent & Child details if child name only "abc". This is my sample code

Parent entity

@Entity
@Table(name = "parent")
public class Parent {

    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "parent_id")
    private Long parentId;
    
    ....

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "mappingParentId")
    private Collection<ParentChildMapping> parentChildMappingCollection;
}

Parent child mapping entity

@Entity
@Table(name = "parent_child_mapping")
public class ParentChildMapping{

    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "mapping_id")
    private Long mappingId;
       
    @JoinColumn(name = "mapping_child_id")
    @ManyToOne(optional = false)
    private ChildEntity mappingChildId;
    
    @JoinColumn(name = "mapping_parent_id")
    @ManyToOne(optional = false)
    private ParentEntity mappingParentId;
}

Child entity

@Data
@Entity
@Table(name = "child")
public class Child implements Serializable 
{
    private static final long serialVersionUID = 1L;
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "child_id")
    private Long childId;
    
    @Basic(optional = false)
    @NotNull
    @Size(min = 1, max = 255)
    @Column(name = "child_name")
    private String childName;
}

current implementation logic

Child child = new Child(); 
        child.setChildName("abc"); //setting the required child name
        
        ParentChildMapping parentChildMapping = new ParentChildMapping();
        parentChildMapping.setMappingChildId(child); //setting the child to mapping
        
        List<ParentChildMapping> parentChildMappingArray = new ArrayList<>();
        parentChildMappingArray.add(parentChildMapping); //setting mapping to mapping collection
        
        Parent parent =  new Parent();
        parent.setParentChildMappingCollection(parentChildMappingArray); //finally set mapping collection to parent
        
        CriteriaQuery<Parent> criteriaQuery = criteriaBuilder.createQuery(Parent.class);
        Root<Parent> root = criteriaQuery.from(Parent.class);
        criteriaQuery.select(root);
        
        List<Predicate> predicateList = new ArrayList<>();  
    
  System.out.println(((List<ParentChildMapping>)parent.getParentChildMappingCollection()).get(0).getMappingChildId().getChildName().trim().toLowerCase()); //abc
    
        //not working, null pointer exception
        predicateList.add(criteriaBuilder.equal(criteriaBuilder.lower(root.<ParentChildMapping>get("parentChildMappingCollection").<ChildEntity>get("mappingChildId").<String>get("childName")), ((List<ParentChildMapping>)parent.getParentChildMappingCollection()).get(0).getMappingChildId().getChildName().trim().toLowerCase()));
    
        criteriaQuery.where(predicate);

I want to return the Parent & Child if child name only "abc".

I am trying to implement this

  SELECT p.parent_id
  FROM parent p
  JOIN parent_child_mapping pcmap on p.parent_id = pcmap.mapping_parent_id
  JOIN child c on pcmap.mapping_child_id = c.child_id
  WHERE c.child_name = 'abc'

I hope you understand this question.

You will have to use an EXISTS predicate to only return Parent if one of the children names match. See How to check if entity in set contains a certain value using criteriaBuilder? for details.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM