Join in #NamedQuery: Unexpected token ON - java

In Hibernate, I created a query using JOIN to join two tables. The query executes fine in Oracles SQL Developer. However, if I add it to a #NamedQuery, the server starts with this error:
Error in named query: loadFooByAnother: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ON near line 1, column xxx
My named query is:
SELECT foo FROM FooTable foo JOIN BarTable bar
ON foo.something=bar.somethingId
WHERE bar.anotherId=:another
Is it not possible to use JOIN .. ON syntax in Hibernate?

You need to use the with directive, if you use HQL:
SELECT foo
FROM FooEntity foo
JOIN foo.bar b with b.name = :name
WHERE foo.prop = :prop
This is for supplying a custom ON clause. From your example, judging from how you joined tables, I think you tried to execute a native SQL using a #NamedQuery.
If you want to run a native SQL query, you have to use #NamedNativeQuery instead.
If you want to use HQL, you need to use Entities and to join Entity associations (not tables).
If you use JPQL then the with directive has to be replaced by the on directive, but again, you need to navigate entity associations, meaning you have to map them first.

Related

How to use CTE expression WITH clause in Spring Data JPA

I want to write a recursive query in SQL Server. So I am using CTE. Query is working properly in SSMS but when I am trying to use the same CTE in JPA as native SQL it gives an error:
Invalid name column Id.
The entity (which I am using in CTE to fetch data recursively) has #Id #Column(name="pk_id") private int Id field.
I also followed this SOQ : cte sql to simple subset query for JPA
But still getting error as invalid name column Id.
I have never used CTE before. How can this be fixed?
You can write the SQL query in JPA Repositories since the #Query annotation takes native query as well. For that, you need to specify the SQL query in the value parameter and nativeQuery is true as follow.
You can write CTE queries as well.
public interface ISomeRepository extends JpaRepository<Entity, Long> {
#Query(value = "SQL QUERY NEED TO BE WRITTEN HERE", nativeQuery = true)
List<Long> getEntityIds();
}

Converting SQL query with joins to JPA

I have this SQL query:
select ts.scorename from content_package cp
join content_package_content_package_components cpcps on cpcps.content_package = cp.id
join content_package_component cpc on cpc.id = cpcps.content_package_components
join tests t on t.id = cpc.assessment
join test_scores ts on ts.tests_id = t.id
where cp.tag = 'C_TS_EN_ABSA_G_'
And want to convert it to JPA, ideally Specifications - is this possible?
you can write this query in JPQL but firs you need to create POJO class of your models. if you are using Intelij idea you can create your models in it by going to persistence section ,right click on your data source and select generate persistence mapping by (hibernate or database schema). after creating models you should change your table names to pojo classes in query and so on ....

How can I do an UPDATE statement with JOIN in JPQL (Spring JPA Queries)?

This is an extension of this question Update Statement with JOIN in SQL but I am trying to use Spring Data JPQL.
I am trying to use Update along with JOIN in JPQL as follows
#Modifying
#Query("UPDATE TotalValue tv JOIN LineItems li WHERE li.totalValue.totalValueId=:totalValuedId SET tv.totalAmount =sum(li.itemTotalValue) ")
void calculateTotalAmount(#Param("totalValuedId") Long totalValuedId);
However, i get an error as follows
org.hibernate.hql.internal.ast.QuerySyntaxException: expecting "set", found 'JOIN'
Is UPDATE and JOIN not possible in JPQL ? What is the alternative. Thanks
The JPQL syntax seems to indicate that a JOIN is actually not possible in an UPDATE statement.

JPA Criteria API: join on another query

I am trying to build this query with JPA Criteria API
SELECT s FROM snapshot s
INNER JOIN (
SELECT collector_id, entity_id, MAX(timestamp) AS "timestamp"
FROM snapshot GROUP BY collector_id, entity_id
) AS j ON s.TIMESTAMP = j.TIMESTAMP AND s.collector_id = j.collector_id AND s.entity_id = j.entity_id;
The inner select should get 3 properties to identify a snapshot, and then the outer select will get all the other properties of a snapshot based on 3 that inner select returned.
I have success with building the inner select, but how to combine the outer select with the inner using a join?
Or, maybe, there is a different way to construct the query itself in a way, that doesn't include a sub query...
EDIT:
Similar quertion: jpa criteria-api: join with subselect
JPA does not support sub-selects in the FROM clause. Some JPA providers may support this.
For example EclipseLink does:
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#Sub-selects_in_FROM_clause

getting result set into DTO with native SQL Query in Hibernate

I have a query like below
select f.id, s.name, ss.name
from first f
left join second s on f.id = s.id
left join second ss on f.sId = ss.id
If I could use HQL, I would have used HQL constructor syntax to directly populate DTO with the result set.
But, since hibernate doesn't allow left join without having an association in place I have to use the Native SQL Query.
Currently I am looping through the result set in JDBC style and populating DTO objects.
Is there any simpler way to achieve it?
You could maybe use a result transformer. Quoting Hibernate 3.2: Transformers for HQL and SQL:
SQL Transformers
With native sql returning non-entity
beans or Map's is often more useful
instead of basic Object[]. With
result transformers that is now
possible.
List resultWithAliasedBean = s.createSQLQuery(
"SELECT st.name as studentName, co.description as courseDescription " +
"FROM Enrolment e " +
"INNER JOIN Student st on e.studentId=st.studentId " +
"INNER JOIN Course co on e.courseCode=co.courseCode")
.addScalar("studentName")
.addScalar("courseDescription")
.setResultTransformer( Transformers.aliasToBean(StudentDTO.class))
.list();
StudentDTO dto =(StudentDTO) resultWithAliasedBean.get(0);
Tip: the addScalar() calls were
required on HSQLDB to make it match a
property name since it returns column
names in all uppercase (e.g.
"STUDENTNAME"). This could also be
solved with a custom transformer that
search the property names instead of
using exact match - maybe we should
provide a fuzzyAliasToBean() method ;)
References
Hibernate Reference Guide
16.1.5. Returning non-managed entities
Hibernate's Blog
Hibernate 3.2: Transformers for HQL and SQL

Categories

Resources