This question already has an answer here:
Externalize query in spring boot application
(1 answer)
Closed 2 years ago.
I am using spring-data JpaRepository.
I have the following native query :
#Query(value = "SELECT SUBSTRING_INDEX(u.email, '#', -1) as domain, COUNT(*) as domainCount, r.invite_organization_id"
+ " FROM srs_users as u,srs_user_registrations as r where u.user_id=r.user_id and r.invite_organization_id=:orgId"
+ " GROUP BY "
+ "SUBSTRING_INDEX(u.email, '#', -1) ORDER BY domainCount DESC", nativeQuery = true)
List<Object[]> countTopDomain(#Param("orgId") String orgId );
Can we externalize the above native query in jpa-named-queries.properties just like other named queries.
You can use JPA Named queries. But I'm afraid that is not exactly what you are looking for. Other than that there is no support of externalizing SQL statements.
At resources create a folder META-INF.
At META-INF create a default file jpa-named-queries.properties
In this file put your query at any unique key. Say,
chk.test1=SELECT SUBSTRING_INDEX(u.email, '#', -1) as domain, COUNT(*) as domainCount, r.invite_organization_id FROM srs_users as u, srs_user_registrations as r where u.user_id=r.user_id and r.invite_organization_id=:orgId GROUP BY SUBSTRING_INDEX(u.email, '#', -1) ORDER BY domainCount DESC
To use this use below code:
#Query(name = "chk.test1", nativeQuery = true)
List<Object[]> countTopDomain(#Param("orgId") String orgId );
Related
We are using Spring Data JPA + Hibernate approach for implementation.
For complex queries with joins we have created a common mapping xml where we are defining those queries.
We are not creating each entity class for these complex queries.
How can we use JPARepository and execute these query?
Is there any way? Below is one of the query written in orm.xml :
SELECT FMT_NAME( pers.id ) AS customer_name, first_name, mid_name,
last_name,
addr.line_1_addr,
addr.line_2_addr,
RTRIM( LTRIM( addr.city_name || ', ' || addr.state_code || ' ' ||
addr.zip_code_num, ', ') || '-' || addr.zip_code_suffix, '-' ) AS line_3_addr
FROM pers, (SELECT pers_addr.pers_id ,
addr.line_1_addr, addr.line_2_addr,
addr.city_name, addr.state_code,
addr.zip_code_num, addr.zip_code_suffix
FROM pers_addr, addr WHERE addr.id = pers_addr.addr_id
AND TRUNC(SYSDATE) BETWEEN pers_addr.beg_date AND pers_addr.end_date
AND pers_addr.type_code = 'ML'
) addr WHERE pers.id = ? AND pers.id = addr.PERS_ID
You can make use select new the resource for your ordinary class. For example, I have the mapping classes Student, Team, School, Subject and want to get some data from these entities. And build an ordinary class StudentData
So I can do a query(#Query or #NamedQuery) like that:
select new com.my.package.vo.StudentData(student, teacher, subject) from Stutdent student inner join student.team inner join team.teacher ....
I am trying to use postgresql jsonb operators with spring data jpa query as:
#Query(value="SELECT * from Employee e WHERE e.details #> '{\"province\":{\"city\":{\"town\": \":town\"}}, \"hobbies\": [\":hobby\"]}'",nativeQuery = true)
town and hobby are inputs.
There is no error but no result is returned, though records are there which meets the criteria
It seems parameter binding is not working.
What can be the solution?
Here, :town and :hobby is inside ''(single quote) means string literal, so parameter can't be replaced. You can use || to concat as string so that parameters are not inside in '' and can be replaced.
#Query(value="SELECT * from Employee e WHERE e.details #> ''||'{\"province\":{\"city\":{\"town\": \"' || :town || '\"}}, \"hobbies\": [\"' || :hobby || '\"]}'||'' ", nativeQuery = true)
I have query like that:
#Query(value = "SELECT new com.domain.ActivityStatistic( " +
"adm.id, " +
"adm.fullName, " +
"COUNT(CASE WHEN (act.action = 'APPROVE') THEN act.action END) AS approved, " +
"max(act.actionTime) AS lastActionTime) " +
"FROM Actions act, Admins adm LEFT JOIN adm.group gr " +
"WHERE adm.id = act.adminId AND act.actionTime BETWEEN ?1 AND ?2 AND gr.id = ?3 " +
"GROUP BY adm.id")
Page<ActivityStatistic> getActivityStatistics(LocalDateTime from,
LocalDateTime to,
long groupId,
Pageable pageable);
How can I sort it by the new field that I created: lastActionTime, approved ?
I can run it by native sql in postgresql: pgadmin. But in jpa, when I using sort with field name is approved, it auto become act.approved in JPA query.
I used to read this post Spring Data and how to sort by a column not in an Entity but it not help.
You can't apply in JPQL on a table column that isn't mapped to a property of an entity.
The reason for this is that JPA including JPQL operates on these entities.
Use a native query instead.
String q = "select id from Calendar c " +
"where c.isActive = 1 and " +
"date_part('dow', '2017-09-19 13:23:23'::date) = c.frequencyValue)";
Query query = em.createQuery(q);
List results = query.getResultList();
If I include ::date, hibernate would complain because : conflicts with parameter, but if I don't, postgres will complain. Could not choose a best candidate function. You might need to add explicit type casts. What can I do?
https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-expressions
as specified extract function should work if the underlying db supports them so:
extract(dow from date '2017-09-19 13:23:23');
should works
So the query below is probably not the most efficient, buy still, I am wondering why it is returning no result, even though the SQL counterpart does. There is no error, I am just getting no result. Is it maybe not the correct equivalent for the query I wrote in MySQL?
This is the JPA JPQL.
Query query = em.createQuery("SELECT sub FROM Subscription sub WHERE "
+ "sub.isSuspended = 0 AND "
+ "(SELECT i FROM Invoice i WHERE i.dateDue < CURRENT_DATE AND i.datePaid IS NULL "
+ "GROUP BY i HAVING COUNT(i.idInvoice) > 2) MEMBER OF sub.invoices");
And this is the SQL from MySQL.
SELECT * from subscription
WHERE subscription.is_suspended = 0 AND id_subscription IN
(SELECT id_subscription FROM invoice
WHERE date_due < CURDATE() AND date_paid IS NULL
GROUP BY id_subscription
HAVING COUNT(*) > 2)
The two queries are not the same. To use the actual query use the NativeQuery createNativeQuery() instead of Query.
In your case the JPA version seems to have syntax errors.
After the AND you are missing the IN operator.
In the nested query you are selecting i instead of something like i.idInvoice
The JPA query should look like
SELECT sub FROM Subscription sub
WHERE sub.isSuspended = 0
AND sub.idSubscription IN
(SELECT i.idInvoice
FROM Invoice i
WHERE i.dateDue < CURRENT_DATE AND i.datePaid IS NULL
GROUP BY i.idInvoice
HAVING COUNT(i.idInvoice) > 2);