5

Say i have the below JPA method :

public List<FrequencyCode> findAllByNameContainingAndAllowExplicitDosingTimesEqualsOrderByName(String name, Boolean allowExplicitDosingTimes); 

This method is called by a user filtering a list of these objects with an input field and a select field :

enter image description here

The boolean value can be true, false or null in this case if the user is not making a search with that field. It looks like JPA is ACTUALLY searching for a null value when i would like it to ignore any null values. I have been able to make this combined search work with the below code :

@Override public List<FrequencyCode> findAllWithFilters(String name, Boolean allowExplicitDosingTimes) { if (allowExplicitDosingTimes == null) { return ((FrequencyCodeRepository) baseRepository).findAllByNameContainingOrderByName(name); } else if (allowExplicitDosingTimes == true) { return ((FrequencyCodeRepository) baseRepository).findAllByNameContainingAndAllowExplicitDosingTimesTrueOrderByName(name); } else if (allowExplicitDosingTimes == false) { return ((FrequencyCodeRepository) baseRepository).findAllByNameContainingAndAllowExplicitDosingTimesFalseOrderByName(name); } return null; } 

This works but, obviously, on a page with 8 search options this would become a nightmare. The String parameters do not have this problem because they are actually an empty String when the user doesn't choose a filter. This paired with the Containing keyword, any value contains "" so it behaves as if that parameter is ignored which is exactly what I want for other types. Is there a way for a JPA findAll...() method to simply ignore null parameters?

******SOLUTION******

Here is how i made this work with the help of the accepted answer :

FrequencyCode fc = new FrequencyCode(); fc.setName(name); fc.setAllowExplicitDosingTimes(allowExplicitDosingTimes); ExampleMatcher matcher = ExampleMatcher.matching() .withMatcher("name", match -> match.contains()) .withMatcher("allowExplicitDosingTimes", match -> match.exact()) .withIgnorePaths("id", "uuid") .withIgnoreNullValues(); Example<FrequencyCode> example = Example.of(fc, matcher); List<FrequencyCode> frequencyCodes = ((FrequencyCodeRepository) baseRepository).findAll(example); 

You HAVE to tell it to ignore any ID fields or really any other fields you do not intend to search with but this is INCREDIBLY powerful!

Thanks!

1
  • check out Spring Data Specifications Commented Feb 8, 2019 at 15:02

1 Answer 1

3

You can use Example like this

@Override public List<FrequencyCode> findAllWithFilters(String name, Boolean allowExplicitDosingTimes) { FrequencyCode fc = new FrequencyCode(); //I assume that you have setters like bellow fc.setName(name); fc.setAllowExplicitDosingTimes(allowExplicitDosingTimes); ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues(); Example<FrequencyCode> example = Example.of(fc, matcher); return ((FrequencyCodeRepository) baseRepository).findAll(example); } 
Sign up to request clarification or add additional context in comments.

2 Comments

I tried this and it always returns an empty list even if i input the exact same values the object has
In researching a bit on the ExampleMatcher i was able to make it work exactly the way i want to and eliminate a LOT of code from my app! Spring Data is incredibly powerful, thank you!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.