How to implement filtering where the entities have many-to-many relationship, without using JPA Specification?

How-To/Tutorial

So the Owning side is the Problem enitity and the inverse is the Tags Entity.

(name = "problem")
public class Problem {

    String problemCode
;

    
    (strategy = GenerationType.
IDENTITY
)
    Long problemId
;

    
    String problemName
;
    
String contest
;
    
String platform
;

    
(EnumType.
STRING
)
    Status status
;

    
/*
    * when user sends in the payload the tags are going to be a list of strings containing the tag name
    * it will throw an error for tagset cuz it expects a set of tags object.
    * So through this field, set of strings we can it the input
    * process it in the problem service layer by calling the agservice methos that convert the set of strings
    * to set of Tags object
    * After which we set the tagset value to the returned value, to ensure consistent type handling.
    * it is marked as  because: we dont want to create any field in the database for this strings set. it is used just for the
    * input processing purpose.*/
    
    Set<String> tags
;

    
String url
;
    
String notes
;

    
/*
    * JsonIgnore cuz we don't want to see the whole tags set in the response output at all.*/
    
    
    (name="problem_tag"
,
     
joinColumns = (name = "problemId")
,
     
inverseJoinColumns = [u/JoinColumn](/u/JoinColumn)(name = "tagId")
    )
    Set<Tags> tagSet = new HashSet<>()
;
}

This is the tags entity.

(name="tags")
public class Tags {

    
    (strategy = GenerationType.
IDENTITY
)
    Long tagId
;

    
(unique = true
, 
nullable = false)
    String tagName
;

    
[u/ManyToMany](/u/ManyToMany)(mappedBy = "tagSet")
    Set<Problem> problemSet = new HashSet<>()
;
}

The controller for the /GET problem is

public ResponseEntity<List<Problem>> getAllProblems(@RequestParam(required = false) String status
, 
(required = false) String platform
,
                                                    
[u/RequestParam](/u/RequestParam)(required = false) List<String> tags)
{

    List<Problem> problems = problemService.getAllProblems(status
, 
platform
, 
tags)
;
    
return new ResponseEntity<>(problems
, 
HttpStatus.
OK
)
;
}

So in the db it is creating a joined table as "problem_tag". I dont want to use JPA Specifications as of yet.

I want to learn how to implement it such that I am querying just the filtered problem list using the joined table... instead of querying the whole thing first and then filtering.

As I read in the documentation that for many-to-many this is how we represent it in db, I dont understand how that join table is getting used.

I am still learning spring boot, so I am focusing on these things.

Thank you for your help. I will really appreaciate your direction and help.

Posted May 2, 2026, 2:04 PM UTC

78
Loading comments…