how to use JPA Native query and TypedParameterValue to perform count

笑着哭i 提交于 2021-01-29 14:20:14

问题


I have an Entity class and I want to count the number of elements that satisfy some conditions in a PostgreSQL database.

The entity contains many columns but I just need a response that returns the count of the selected columns as pending, approved, notSubmitted, submitted, approved, notapproved, queried...

In order to avoid type mismatch from PostgreSQL driver, I am using the TypedParameterValue method. However I am getting a null value as a response instead of the actual value that should be fetched by the query.

For example, I am getting :

{
    "status": "OK",
    "success": true,
    "errorCode": 0,
    "data": [
        null
    ],
    "message": "See Data Object for Details"
 

instead of:


"status": "OK",
    "success": true,
    "errorCode": 0,
    "data": {
        "approved": 1000,
        "totalApplications": 2000,
        "submitted": 560,
        "notSubmitted": 880,
        "pending": 30,
        "queried": 60,
        "notApproved": 70
    },
    "message": "See Data Object for Details"
 

This the request I sent from postman

{
"startDate": "2014-06-11",
"endDate": "2020-10-14",
"processTypeFk":9542,
"companyTypeId": 6995

    }

Below is my code:

    @PostMapping("/date-sum")
    public ResponseEntity<Object> sumAnnualReturnRecordsWithDate(@RequestBody SearcherDto searcherDto) {

        Long companyType = searcherDto.getCompanyTypeId();
        Long processType = searcherDto.getProcessTypeFk();
        Long processType1 = searcherDto.getProcessTypeFk1();
        Long processType2 = searcherDto.getProcessTypeFk2();
        Long processType3 = searcherDto.getProcessTypeFk3();
        LocalDateTime start = LocalDateTime.of(LocalDate.from(searcherDto.getStartDate()), LocalTime.of(0, 0, 0));
        LocalDateTime end = LocalDateTime.of(LocalDate.from(searcherDto.getEndDate()), LocalTime.of(23, 59, 59));


             Query q = em.createNativeQuery("SELECT null AS id, sum(case when (IS_QUERIED = false AND SUBMITTED = true) then b.AMOUNT else null end) AS pending, " +
                     " sum(case when (SUBMITTED = false OR SUBMITTED IS NULL) then b.AMOUNT else null end) AS notSubmitted, " +
                     " sum(case when ( (SUBMITTED = true)) then 1 else null end) AS submitted, " +
                     " sum(b.AMOUNT) AS totalApplications, " +
                     " sum(case when (IS_QUERIED = true ) then b.AMOUNT else null end) AS queried," +
                     " sum(case when (APPROVED = true) then b.AMOUNT else null end) AS approved, " +
                     " sum(case when (APPROVED = false) then b.AMOUNT else null end) AS notApproved " +
                     " FROM ANNUAL_RETURNS a " +
                     " LEFT JOIN PAYMENT_HISTORY b ON b.PROCESS_TYPE_FK = a.PROCESS_TYPE_FK" +
                     " LEFT JOIN COMPANY c ON c.id= a.COMPANY_FK " +
                     " WHERE (a.FINANCIAL_YEAR_END >=:startDate AND a.FINANCIAL_YEAR_END <=:endDate) AND " +
                     " b.PAYMENT_STATUS='APPROVED' AND (c.COMPANY_TYPE_FK=:companyTypeId OR :companyTypeId=0) " +
                     " AND (a.PROCESS_TYPE_FK =:processTypeFk OR " +
                     " (:processTypeFk1=9542 AND :processTypeFk2=9594 AND :processTypeFk3=9598)) ", AnnualReturn.class);

        q.setParameter("processTypeFk", new TypedParameterValue(LongType.INSTANCE, processType));
        q.setParameter("processTypeFk1", new TypedParameterValue(LongType.INSTANCE, processType1));
        q.setParameter("processTypeFk2", new TypedParameterValue(LongType.INSTANCE, processType2));
        q.setParameter("processTypeFk3", new TypedParameterValue(LongType.INSTANCE, processType3));
        q.setParameter("companyTypeId", new TypedParameterValue(LongType.INSTANCE, companyType));
        // these are never null, so we don't need to type-set them.
        q.setParameter("startDate", start);
        q.setParameter("endDate", end);
        List <AnnualReturn> countList=q.getResultList();


        return ResponseEntity.ok(new JsonResponse("See Data Object for Details", countList));
    }

Here is the main Entity class:

@Entity
@Table(name="ANNUAL_RETURNS")
public class AnnualReturn implements Serializable {

    private static final long serialVersionUID = 1L;


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    private Long id;

    @Column(name = "IS_QUERIED")
    private Boolean queried;

    @Column(name = "FINANCIAL_YEAR_END")
    private String financialYearEnd;
    @Column(name = "FINANCIAL_YEAR_START")
    private String financialYearStart;

    @Column(name = "FINANCIAL_YEAR")
    private String financialYear;

    private Boolean approved;

    @Column(name = "APPROVAL_DATE")
    private Date approvalDate;

    @ManyToOne
    @JoinColumn(name = "COMPANY_FK")
    private Company company;

    @ManyToOne
    @JoinColumn(name = "PROCESS_TYPE_FK",referencedColumnName = "id")
    private Process_Type processType;

}

Please help me with ideas and possible solutions.

来源:https://stackoverflow.com/questions/64660717/how-to-use-jpa-native-query-and-typedparametervalue-to-perform-count

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!