spring-bootcriteria-apicriteriaquerycriteriabuilder

Criteria Builder Multiple Joins


I have 4 different tables on which Joins are applied and this is working fine with SQL Query

    SELECT donor.title, SUM(donation.donated_amount) + SUM(donation.gift_aid),    
    SUM(donation.donated_amount)
    FROM checkout checkout
    JOIN donation donation ON donation.checkout_id = checkout.id
    JOIN donor donor ON checkout.donor_id = donor.donor_id
    JOIN company company ON company.id = donor.company_id
    WHERE donation.donation_status = 1
    GROUP BY donor.title;

Now I have to implment filters on the result set so I implemented this Criteria Builder Stuff.

    CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    CriteriaQuery<DonorReportResponseDTO> criteriaQuery = criteriaBuilder.createQuery(DonorReportResponseDTO.class);
    Root<Checkout> checkout = criteriaQuery.from(Checkout.class);
    Join<Checkout, Donation> donation = checkout.join(Checkout_.donation);
    Join<Checkout, Donor> donor = checkout.join(Checkout_.donor);
    Join<Donor, Company> company = donor.join(Donor_.company);

But this is giving this error on first Join statement.

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause java.lang.NullPointerException: null at org.hibernate.query.criteria.internal.path.AbstractFromImpl.constructJoin(AbstractFromImpl.java:293)
at org.hibernate.query.criteria.internal.path.AbstractFromImpl.join(AbstractFromImpl.java:279)
at com.netsol.fareshare.auth.repository.DonationRepositoryImpl.getDonorDetailReportByCriteria(DonationRepositoryImpl.java:35)
at com.netsol.fareshare.auth.repository.DonationRepositoryImpl$$FastClassBySpringCGLIB$$32b471a5.invoke(<generated>)

Solution

  • In the current scenario Metamodel was not picked by Join statement

    Join<Checkout, Donation> donation = checkout.join(Checkout_.donation);
    

    So I changed the Metamodel class instance to the variable I specified in Campaign Entity like this

    Join<Checkout, Donation> donation = checkout.join("donation");
    

    And changed it in all joins, group by and multiselect.