I am trying to write a native query and pagination in eclipse link + JPA for PostgreSQL
but I'm getting exceptions :
Here is the code what I tried :
#Query(nativeQuery = true, value= "select a.* from rqst a LEFT OUTER JOIN table_b b ON a.id= b.id where a.code='abc' ORDER BY /*#pagable*/")
#Query(nativeQuery = true, value= "select a.* from rqst a LEFT OUTER JOIN table_b b ON a.id= b.id where a.code='abc' ORDER BY ?#{#pageable}")
and I followed this link but no luck :
Spring Data and Native Query with pagination
any help appreciated
when I use second query I got this exception :
Can't infer the SQL type to use for an instance of org.springframework.data.domain.PageRequest. Use setObject() with an explicit Types value to specify the type to use.
at org.postgresql.jdbc.PgPreparedStatement.setObject(PgPreparedStatement.java:1039) ~[postgresql-9.4.1208.jar:9.4.1208]
Related
I have the following JPQL query being mapped to a custom projection. The query is working correctly until I set the size attribute at the pagination object.
#Query(value = "SELECT EXTRACT(WEEK FROM e.time) AS week "
+ "COUNT(r.id) AS total FROM MyEntity e "
+ "LEFT JOIN e.relationship r GROUP BY week")
Page<WeeklyReport> findWeeklyReport(Pageable pageable);
Hibernate fails with the error java.sql.SQLSyntaxErrorException: Unknown column 'week' in 'group statement' after running the following query:
select count(entity0_.id) as col_0_0_ from entity entity0_
left outer join relationship relationship1_ on entity0_.id=relationship1_.tide_id
group by week
How can I have the same query without my group name break the pagination above?
The error does not happen if the size is not defined.
Anyone knows how to write join fetch query with jooq ?
my code :
int oid=5;
Select<?> selectQuery = DSL_CONTEXT.select().from(TABLE_A)
.join(TABLE_B).on(TABLE_A.PID.eq(TABLE_B.ID))
.where(TABLE_A.OID.eq(oid))
.orderBy(UPDATED.asc(), ID.asc())
.seekAfter(val(offsetDateTime), val(id))
.limit(50);
this results in : select * from table_a join table_b type of query. How to make it create a query of following type :
select * from table_a join fetch table b ...
Any help is appreciated.
The closest you can get with jOOQ 3.11 out of the box functionality is using ResultQuery.fetchGroups(). On your query, call:
Map<TableARecord, Result<TableBRecord>> result = select.fetchGroups(TABLE_A, TABLE_B);
I have a query that has more columns then what my entity class has.
In order to not let hibernate complaints, I have to add an annotation to the field like
#Transient
private Integer count;
But by doing this makes hibernate not able to map count. Let's say my query is
session.createSQLQuery("SELECT p.*, count(p.id), sqrt(1+2) as distance FROM post p group by p.id")
I know the query doesn't make any logical sense. This is just for example. The columns return from query above will have everything in post and two extra columns, count and distance. I wanted to map the result to my entity with count and distance are annotated with #Transient, or if there's a better way to map the result. I'm more than happy to do so. The goal is not to do this in an entity but a class with mapped result. I've tried calling addEntity() but doesn't seem to help.
You can use Result Set Transformer to achieve this.
Step 1 ) Create a new DTO class with all the fields that you query going to return
Step 2 ) Add the below line
setResultTransformer( Transformers.aliasToBean(DTO.class))
Example :
List resultWithAliasedBean = session.createQuery(
"SELECT p.*, count(p.id), sqrt(1+2) as distance FROM post p group by p.id")
.setResultTransformer(Transformers.aliasToBean(DTO.class))
.list();
DTO dto = (DTO) resultWithAliasedBean.get(0);
Note : Make sure the field names in the DTO class match the column name which your query is returning.
I see that you are using Hibernate so Yathish answer works fine.
But if you want to do it with JPA spec then you can use Result Set Mapping
Query q = em.createNativeQuery(
"SELECT c.id, c.name, COUNT(o) as orderCount, AVG(o.price) AS avgOrder " +
"FROM Customer c " +
"JOIN Orders o ON o.cid = c.id " +
"GROUP BY c.id, c.name",
"CustomerDetailsResult");
#SqlResultSetMapping(name="CustomerDetailsResult",
classes={
#ConstructorResult(targetClass=com.acme.CustomerDetails.class,
columns={
#ColumnResult(name="id"),
#ColumnResult(name="name"),
#ColumnResult(name="orderCount"),
#ColumnResult(name="avgOrder", type=Double.class)})
})
There you have to specifiy the mappin of the columns from the SQL result set to the DTO.
And if you think this is to complicated there is a open source project called QLRM (Query Lanaguage Result Mapper) that mapps any SQL statement to a POJO.
http://simasch.github.io/qlrm/
And last but not least if you will do extensive SQL processing why not have a look at jOOQ: https://www.jooq.org/
SELECT recipe.name,SUM(salesdetails.quantity::integer),recipe.price As Quantity
FROM (salesinfo JOIN salesdetails ON salesinfo.sessionid=salesdetails.salesinfo_sessionid)
JOIN recipe ON salesdetails.recipe_id=recipe.id group by salesdetails.recipe_id,recipe.name,recipe.price
ORDER BY SUM(salesdetails.quantity::integer) DESC;
Can anyone give me the hql query for this?
If you are not acquainted with the HQL and want to use the same query ,then you can do it using the native query feature of the Hibernate like this :
#QUERY(value="SELECT recipe.name, SUM(salesdetails.quantity::
INTEGER),recipe.price AS Quantity
FROM (salesinfo
JOIN salesdetails ON salesinfo.sessionid=salesdetails.salesinfo_sessionid)
JOIN recipe ON salesdetails.recipe_id=recipe.id
GROUP BY salesdetails.recipe_id,recipe.name,recipe.price
ORDER BY SUM(salesdetails.quantity:: INTEGER) DESC", nativeQuery = TRUE)
But I would recommend that you first try to convert the same in into HQL query and then if any issue then you should ask it here instead of directly asking for the converted query. Meanwhile this can help.
I have a MySql query like this:
select AK.*, max(AA.activityDate)
from AssessmentKey AK
join AssessmentActivity AA on AA.ASSESSMENTKEY_ID = AK.id
group by AK.id having max(AA.activityDate) <= '2012-10-02 17:30:55'
Is there a way to convert into in JPA NamedQuery. I am using OpenJPA.
If I put it directly into:
#NamedQuery(name = "AssessmentActivity.findByDate",
query = "select AK.*, max(AA.activityDate) from AssessmentKey AK
join AssessmentActivity AA on AA.ASSESSMENTKEY_ID = AK.id
group by AK.id having max(AA.activityDate) <= '2012-10-02 17:30:55'")
The error is showed here: select AK.* that identifier expected, got "*" and also it does not like on, here it says:
How can I resolve this problem?
First problem: you should replace AK.* with AK you just need the entity alias here.
Second problem: join syntax is not like that. You should write: join and navigate through the object references,eg: AK.assesmentActivity and use the where keyword instead of on
Here's a tip on join: JPQL join
Remember: you are in the ORM, dealing with Entities and their properties, not DB foreign keys and columns.
(ps: Maybe you wanted to write a NativeQuery? There you can use native SQL syntax)
EDIT:
(on your comment) So you must start your query from AA:
select AK from AssesmentActivity AA join AssesmentKey AK where AA.assesmentKey = AK ...
This way you can join them.