简体   繁体   English

如何将 JPA 创建本机查询映射到投影

[英]How to Map a JPA create native query to projections

I am trying to get count from a postgreSQL database using Spring Data JPA createNativeQuery.我正在尝试使用 Spring Data JPA createNativeQuery 从 postgreSQL 数据库中获取计数。 However, the query is returning null instead of the actual values.但是,查询返回的是 null 而不是实际值。

Here is the JPA createNativeQuery statement below:下面是 JPA createNativeQuery 语句:

Query q = entityManager.createNativeQuery("SELECT null AS id, 
count(case when (IS_QUERIED = false AND SUBMITTED = true) 
then 1 else null end) AS pending,  
count(case when ( (SUBMITTED = true)) then 1 else null end) AS submitted, 
count(*) AS totalApplications FROM ANNUAL_RETURNS ", AnnualReturn.class);
//Note: AnnualReturn is the name of the @Entity class

List <AnnualReturn> countList=q.getResultList();

return countList;

I need help mapping the "submitted", "pending" and "totalApplications" instances from my query in a way that returns the result as below.我需要帮助以返回如下结果的方式从我的查询映射“已提交”、“待处理”和“总应用程序”实例。

Result expected is:预期结果是:

"data": {
        "totalApplications": 2000,
        "submitted": 560,
        "pending": 60,
    }

Result am getting:结果得到:

{
    "data": [
        null
    ]

I would appreciate any help.我将不胜感激任何帮助。

You shouldn't use a typed Query here, try something like您不应该在此处使用类型化查询,请尝试类似

Query q = entityManager.createNativeQuery("SELECT " +
  " COALESCE(sum(case when (IS_QUERIED = false AND SUBMITTED = true) " +
  " then AMOUNT else 0 end),0) AS pending,  " +
  " COALESCE(sum(case when ( (SUBMITTED = true)) then 1 else 0 end),0) AS submitted, " +
  " COALESCE(sum(AMOUNT),0) AS totalApplications FROM ANNUAL_RETURNS ");

List <Object[]> countList=q.getResultList();

Object[] obj = countList.get(0);

for (Object value : obj) {
     System.out.println(value);
}
long pending = ((BigInteger)obj[0]).longValue();
long submitted = ((BigInteger)obj[1]).longValue();
long total = ((BigInteger)obj[2]).longValue();


return ...; // prepare the values to your convinience

EDIT编辑

changed null to 0 to avoid possible null values in the result将 null 更改为 0 以避免结果中可能出现空值

EDIT编辑

fixed NPE on empty table在空桌子上固定 NPE

I do not know why but I believe SELECT null AS id is causing null record to be fetched.我不知道为什么,但我相信SELECT null AS id会导致获取空记录。

If you don't want id to be fetched then you can use projection with custom RowMapper or DTO projection.如果您不想获取 id,那么您可以将投影与自定义 RowMapper 或 DTO 投影一起使用。

See below:见下文:

@Entity
@Data
@ToString
class A {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;
    String name;
    int age;

    public A() {
    }
    public A(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

interface ARepo extends JpaRepositoryImplementation<A, Long> {
}

@Component
@RequiredArgsConstructor
class Init {
    final ARepo repo;
    final EntityManager em;

    @EventListener
    public void init(ContextRefreshedEvent evt) {
        repo.save(new A("XX", 5));
        repo.save(new A("ZZ", 6));
        repo.save(new A("AA", 11));
        repo.save(new A("AB", 12));

        Query q = em.createNativeQuery("select 0 as id, a.name as name, a.age as age  from A a where a.total > 10 ", A.class);

        System.out.println(q.getResultList()); //fetches AA and BB 
        //if you change the query to select null as id  it would return [ null, null]
          
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM