wenhao / jpa-spec

A JPA Query By Specification framework.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to search cross join table in @ManyToMany association and combine AND - OR condition in same query

ilentt opened this issue · comments

I have relationship entity like this one

Entity relationship

The Client can login by one or switch login between among Accounts. A Account can login by one or other difference Clients.

Relation Client - Account is many-to-many, so I create a entity ClientAccount to store client and account id.

Client

public class Client {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(name = "brand_name", nullable = false, unique = true)
    private String brandName;
    
    @Column(name = "status")
    private String status;
    
    @Column(name = "date_expire", nullable = false)
    private Long dateExpire;
    
    // bi-directional many-to-one association to ClientAccount
    @OneToMany(mappedBy = "client")
    @JsonManagedReference
    private Set<ClientAccount> clientAccounts = new HashSet<ClientAccount>();
}

Account

public class Account {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(columnDefinition = "bytea", unique = true, nullable = true)
    private String email;
    @Column(columnDefinition = "text", name = "user_name")
    private String userName;
    @Column(columnDefinition = "text", name = "first_name")
    private String firstName;
    @Column(columnDefinition = "text", name = "last_name")
    private String lastName;
    
    // bi-directional many-to-one association to ClientAccount
    @OneToMany(mappedBy = "account")
    @JsonManagedReference
    private Set<ClientAccount> clientAccounts;
}

ClientAccount

public class ClientAccount {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "account_id")
    private Long accountId;
    @Column(name = "client_id")
    private Long clientId;
    
    // bi-directional many-to-one association to Client
    @ManyToOne
    @MapsId("clientId")
    @JsonBackReference
    @JoinColumn(name = "client_id", insertable = true, updatable = true)
    private Client client;

    // bi-directional many-to-one association to Account
    @ManyToOne
    @MapsId("accountId")
    @JsonBackReference
    @JoinColumn(name = "account_id", insertable = true, updatable = true)
    private Account account;
}

In case need search by branchName or firstName or lastName or email via input keyword, how is implement?

I see in your guideline example only show AND condition, how can I combine between AND and OR in query while join multiple table in this case is 3 tables(Client, ClientAccount, Account)

Specification<Client> searchClientAccountByKeyword(String keyword) {
    // how can implement Client join ClientAccount join Account and combine filter condition by keyword?
    // Client.join.ClientAccount.join.Account.and(branchName equal keyword or firstName equal keyword or ,....)
}