Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA and aggregate functions. How do I use the result of the query?

Tags:

java

sql

jpa

I'm new to ORM stuff and I need some help understanding something.

Let's assume I have the following standard SQL query:

SELECT *, COUNT(test.testId) AS noTests FROM inspection
LEFT JOIN test ON inspection.inspId = test.inspId
GROUP BY inspection.inspId

which I want to use in JPA.

I have an Inspection entity with a one-to-many relationship to a Test entity. (an inspection has many tests) I tried writing this in JPQL:

Query query = em.createQuery("SELECT insp, COUNT(???what???) " +
      "FROM Inspection insp LEFT JOIN insp.testList " +  
      "GROUP BY insp.inspId");

1) How do I write the COUNT clause? I'd have to apply count to elements from the test table but testList is a collection, so I can't do smth like COUNT(insp.testList.testId)

2) Assuming 1 is resolved, what type of object will be returned. It will definitely not be an Inspection object... How do I use the result?

like image 952
Bogdan Avatar asked May 26 '10 09:05

Bogdan


People also ask

What are three methods to execute queries in JPA?

There are three basic types of JPA Queries:Query, written in Java Persistence Query Language (JPQL) syntax. NativeQuery, written in plain SQL syntax.

How does JPA query work?

Java Persistence Query languageIt is used to create queries against entities to store in a relational database. JPQL is developed based on SQL syntax. But it won't affect the database directly. JPQL can retrieve information or data using SELECT clause, can do bulk updates using UPDATE clause and DELETE clause.

What is aggregated query?

An aggregate query is a method of deriving group and subgroup data by analysis of a set of individual data entries. The term is frequently used by database developers and database administrators.

How do I return Dtos from native queries?

The easiest way to use this projection is to define your query as a @NamedNativeQuery and assign an @SqlResultSetMapping that defines a constructor result mapping. The instantiation of the DTO objects is then handled by the underlying persistence provider when Spring Data JPA executes the @NamedNativeQuery.


1 Answers

  1. You can give an alias to the joined entity (with AS)
  2. You can create either a new object, or a List with the returned values

So:

SELECT new com.yourproject.ResultHolder(insp, COUNT(test.testId)) 
    FROM Inspection insp LEFT JOIN  insp.testList AS test GROUP BY insp.inspId

Or

SELECT new list(insp, COUNT(test.testId)) 
    FROM Inspection insp LEFT JOIN  insp.testList AS test GROUP BY insp.inspId

The result is then accessible either as an instance of ResultHolder, or as a java.util.List, where the insp is list.get(0), and the count is list.get(1)

like image 140
Bozho Avatar answered Oct 11 '22 12:10

Bozho