skip to Main Content

I have a form in Angular which looks like so

enter image description here

The user can input only the field he wants and I send the form to Spring Rest API like so

{
    "symbol": "DOL",
    "currency": "CAD"
}

From there how to redirect the JPA repository query. I mean if the user only select symbol then the query will be findAllBySymbol ; if the user select the symbol AND the currency then the query should be findAllBySymbolAndCurrency.

How to approach this? Should I query all and filter out? That does not sound optimal

2

Answers


  1. Chosen as BEST ANSWER

    A bit more details with regards to the dependency required for Maven

        <dependency>
            <groupId>org.hibernate.orm</groupId>
            <artifactId>hibernate-jpamodelgen</artifactId>
            <version>6.1.5.Final</version>
        </dependency>
        <dependency>
            <groupId>jakarta.xml.bind</groupId>
            <artifactId>jakarta.xml.bind-api</artifactId>
            <version>4.0.0</version>
        </dependency>
    

  2. You can achieve that using specifications.

    In order to do that, first extend your repository with the SpecificationExecutor

    public interface YourRepository extends JpaRepository<YourEntity, Long>, JpaSpecificationExecutor<YourEntity> {
    }
    

    In order to easily work with the specifications, it’s advised to add the `jpa-modelgen’ dependency:

    (for gradle groovy)

    annotationProcessor('org.hibernate:hibernate-jpamodelgen:6.5.1.Final')
    

    Then, define the specifications that will be used for the search:

    public class YourSpecifications {
        private YourSpecifications() {
        }
    
        public static Specification<YourEntity> byCurrency(String currency) {
            return (root, query, builder) -> currency != null ? builder.equal(root.get(MoneyEntity_.SYMBOL), currency) : builder.and();
    
        }
    
        public static Specification<YourEntity> bySymbol(String symbol) {
            return (root, query, builder) -> symbol != null ? builder.equal(root.get(MoneyEntity_.SYMBOL), symbol) : builder.and();
        }
    }
    

    Once that’s configured, you can start using the repository by using i.e. findAll or findOne methods:

    return repository.findAll(
                    YourSpecifications.byCurrency(currency)
                    .and(YourSpecifications.bySymbol(symbol))
            );
    

    In the example null is checked within the specification, so that if the symbol is null (not provided), all the results are returned. This should be adapted to your needs.

    In order to explore the specifications in more details, check out the spring docs https://docs.spring.io/spring-data/jpa/reference/jpa/specifications.html, as well as jpa criteria API https://openjpa.apache.org/builds/3.2.2/apache-openjpa/docs/#jpa_overview_criteria

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search