Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for ManyToMany Relation when searching #87

Open
hlchanad opened this issue Oct 14, 2018 · 4 comments
Open

Support for ManyToMany Relation when searching #87

hlchanad opened this issue Oct 14, 2018 · 4 comments

Comments

@hlchanad
Copy link

Does this library support ManyToMany relation when searching ?

For example, there are two table, user and role. Each user may has different roles, and each role may be used by different user. Therefore there is one more relation table user_role. In the user datatable, I want to show the roles attached to the user. I can add a List<Role> roles property with annoation @ManyToMany in User class and of cause I can show the roles in the datatable. But the searching function is not working with this field.

@darrachequesne
Copy link
Owner

Not by default, since we try to prevent firstResult/maxResults specified with collection fetch; applying in memory errors, which happens when one entity has a @OneToMany or a @ManyToMany relationship (and gets spanned over multiple lines in the query results).

You should be able to add a Specification though:

userRepository.findAll(input, (root, query, criteriaBuilder) -> {
    return criteriaBuilder.equal(root.join("role", JoinType.INNER).get("name"), roleName);
});

@nugrohotanjo
Copy link

roleName

what is roleName? from where you get the roleName?

@risavkarna
Copy link

Not by default, since we try to prevent firstResult/maxResults specified with collection fetch; applying in memory errors, which happens when one entity has a @OneToMany or a @ManyToMany relationship (and gets spanned over multiple lines in the query results).

You should be able to add a Specification though:

userRepository.findAll(input, (root, query, criteriaBuilder) -> {
    return criteriaBuilder.equal(root.join("role", JoinType.INNER).get("name"), roleName);
});

Could you give a complete example here?

@syfercv
Copy link

syfercv commented Mar 13, 2020

So I had this problem, where I have a datatable of users that have a many-to-many relation with roles and I want for the global search to find user my role.name
I got it to work like this with a List to allow more predicates if you want.

public DataTablesOutput<User> getAllUsers(DataTablesInput input){
		if(!StringUtils.hasText(input.getSearch().getValue())) {
			return userRepository.findAll(input);
		}
		DataTablesOutput<User> udo = userRepository.findAll(input, (root, query, builder) -> {
			List<Predicate> predicates = new ArrayList<>();
			String search = input.getSearch().getValue().toLowerCase();
			Join<User, Role> roles = root.join("roles");
			predicates.add(builder.like(roles.get("name"), "%" + search + "%"));
		        return builder.or(predicates.toArray(new Predicate[predicates.size()]));
		});
		return udo;
	}

The main problem is that you have to download darrachequesne repository classes, include them in your project as a public interface DataTablesRepositoryCustom and change the DataTablesRepositoryImpl so that the part that is defining the AND's becomes OR's

 Specification.where(specificationBuilder.build())
                      .or(additionalSpecification)
                      .or(preFilteringSpecification),
              specificationBuilder.createPageable());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants