Skip to content
Advertisement

How to use Spring Specification to filter through many to many realtionship?

I decided to create filters in my application with Spring Specification. Everything was going well but I don’t know to do filter User events. Which filter events by user login.

My entities look like this:

@Entity
public class EventEntity {
    
    @Id
    private Long id;
    
    @ManyToMany(mappedBy="events")
    private Set<UserEntity> participants = new HashSet<>();
}
@Entity
public class UserEntity {
    
    @Id
    private String login;
    
    @ManyToMany
    @JoinTable(
            name="user_events",
            joinColumns = @JoinColumn(name = "user_login"),
            inverseJoinColumns = @JoinColumn(name = "event_id")
    )
    private Set<EventEntity> events = new HashSet<>();
}

I read many subjects on stack but still don’t know to how to implement my filter logic and filter beginning looks like this:

    private Specification<EventEntity> findUserEvent(String login) {
        return (root, cq, cb) -> {
            if(login.isEmpty()) return cb.conjunction();
    
            Root<EventEntity> event = cq.from(EventEntity.class);
            Join<EventEntity, UserEntity> users = event.join(EventEntity_.PARTICIPANTS)
            return builder.equals ???
        }
    }

Advertisement

Answer

I created the same models and entered a few sample data.

You can see this data as follows:

enter image description here

Let’s write in your specification code as follows:

private Specification<EventEntity> findUserEvent(String login) {
    return (root, cq, cb) -> {
        if (login.isEmpty()) return cb.conjunction();
        Join<EventEntity, UserEntity> join = root.join("participants");
        return cb.equal(join.get("login"), login);
    };
}

When we use the specification code to get user-c user’s events, 2 events will return.

List<EventEntity> events = eventEntityRepository
        .findAll(findUserEvent("user-c"));
System.out.println(events.size());

If something different is happening, first check that you have records in your database and if the metadata definitions contain correct values.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement