How to write inner join query in JPARepository - java

I have the following query which runs perfectly in MySQL but it gives an error when I written in repository How can I write inner join query in JPARepository?
#Query("Select address from Address a inner join Order o ON a.id=o.pickup_address_id where o.customer_id=: customerId AND a.address LIKE 'C%'")
Set<Address> findPickupAddress(#Param("customerId") Long customerId);
Error : unexpected token: Order near line 1, column 66

order is a reserved word. If you can't rename the table you should use it like:
#Query("Select address from Address a inner join `Order` o ON ...")

There is no ON in JPQL so the query is updated as :
#Query("Select a from Address a , Order o where a.id=o.pickupAddress AND o.customer.id=:customerId AND a.address LIKE 'C%'")
Address findPickupAddress(#Param("customerId") Long customerId);
}

Related

Inefficient JPA query using compound Where clause

I have a tables with One-Many Relationships as follows
City->School->Teacher->Children
and my JPQL for retrieving children from a city is as below
#Query("Select c from Children c where c.teacher.school.city=:city")
Set<Children> findChildrenFromCity(#Param("city") City city);
This reference here about Where clause says that
"Compound path expressions make the where clause extremely powerful."
However, upon observing the logs I realise that the above query is doing strange things like
Generate multiple Selects instead of one Select
Some cross joins can be seen in the logs
I am trying to understand if I am defining my query correctly and if the compound Where is indeed so powerful, why is my query so inefficient.
You can use the following method:
Set<Children> findAllByTeacherSchoolCity(String city);
assuming, that your class Children has field Teacher teacher, Teacher has School school and School has String city.
In case there are differences, please ask in comments for clarification.
Try this
#Query("Select c from City city join city.schools s join s.teachers t join t.childrens c where city = :city")
Set<Children> findChildrenFromCity(#Param("city") City city);
This query is running exactly one Select query to fetch the Children entities. Check the below mentioned logs.
HIBERNATE: SELECT childrens3_.id AS id1_0_,
childrens3_.date_created AS date_cre2_0_,
childrens3_.date_updated AS date_upd3_0_,
childrens3_.NAME AS name4_0_,
childrens3_.teacher_id AS teacher_5_0_ FROM city city0_
INNER JOIN school schools1_
ON city0_.id = schools1_.city_id
INNER JOIN teacher teachers2_
ON schools1_.id = teachers2_.school_id
INNER JOIN children childrens3_
ON teachers2_.id = childrens3_.teacher_id WHERE city0_.id = ?
Now what you have is an n+1 issue. To fix such issue you can use join fetch instead of simple joins.
If you want use Query annotation try this approach
#Query("Select c from Children c join fetch c.teacher t join fetch t.school s join fetch s.city ct where ct.id = :id")

join and where clause in hibernate

I am using join and where clause in hibernate 3.but i cant reach the solution.I got the error.
Query qry= session.createQuery("SELECT addemployee.eid,addemployee.fname,addemployee.location,"
+ "empdet.jtitle,empdet.leadname FROM addemployee LEFT JOIN empdet ON addemployee.eid = empdet.eid WHERE (addemployee.eid ='"+id+"')");
List l = qry.list();
Iterator it=l.iterator();
while(it.hasNext())
{
Object rows[] = (Object[])it.next();
System.out.println(rows[0]+separator+rows[1]+separator+rows[2]+separator+rows[3]+separator+rows[4]);
}
Issue: org.hibernate.hql.ast.QuerySyntaxException: unexpected token: ON near line 1, column 127 [SELECT addemployee.eid,addemployee.fname,addemployee.location,empdet.jtitle,empdet.leadname FROM addemployee LEFT JOIN empdet ON addemployee.eid = empdet.eid WHERE (addemployee.eid ='206')]
Try to use session.createSQLQuery() instead.
and don't put enclosed apostrophe (''), you are inputting numbers, not varchar.
like this.
Query qry= session.createSQLQuery("SELECT addemployee.eid,addemployee.fname,addemployee.location,"
+ "empdet.jtitle,empdet.leadname FROM addemployee LEFT JOIN empdet ON addemployee.eid = empdet.eid WHERE (addemployee.eid ="+id+")");
Hibernate Session's createQuery() method requires valid HQL syntax. You can check how to write joins here.
Basically, in HQL you work with your entities, not SQL tables. So you don't need to write ON, because you already map association between entities.
If you still want to write native SQL query, you need to use
session.createSQLQuery(); instead

JPA join query not working

I am trying to use JOIN with JPA. This is my JPA query:
SELECT o FROM Assessment AS o
INNER JOIN AssessmentText at
WHERE o = at.assessment
AND at.localeCode = :localeCode
The relation from the Assessment to AssessmentText is OneToMany.
When I am executing this query I am getting:
org.apache.openjpa.persistence.ArgumentException:
Encountered "INNER JOIN AssessmentText at" at character 31,
but expected: [".", "FETCH", "INNER", "JOIN", "LEFT", <IDENTIFIER>].
I am using JPA implementation: OpenJPA 2.2.1 with MySQL database.
Why do I get this error and how to solve this?
Assuming you want to eager fetch AssessmentText, you can do this (assument Assessment has a member called assessmentText):
SELECT o FROM Assessment AS o LEFT JOIN FETCH o.assessmentText WHERE o.assessmentText.localeCode = :localeCode
You are missing ON in your query It should be something like
SELECT o FROM Assessment AS o INNER JOIN AssessmentText at ON o = at.assessment WHERE at.localeCode = :localeCode
You didn't mention the relationship from Assessment to AssessmentText was - it needs to be used in the join declaration.
The query you do have shows a relationship from AssessmentText to Assessment which can be used if you refactor the query slightly:
SELECT at.assessment FROM AssessmentText at WHERE at.localeCode = :localeCode
Have in mind you should create your query in the following way:
Query query = entityManager.createQuery(queryString);
Not em.createNativeQuery (if you were doing it so).

How to write a join query in HQL

I have 3 tables in DB.
I want to make join query like this:
from Installment i
join Payment p on i.vcode=p.Installment_Vcode and p.vcode=:vcode
but when I run it this error happens:
unexpected token: on near line 1, column 47 [from information.Installment i join Payment p on i.vcode=p.Installment_Vcode]
HQL doesn't have an on operator. Joins can only be done on associations between entities, and can have an optional with clause.

HQL ERROR: Path expected for join

I keep trying variations of this query and can't seem to make this happen. I've also referenced this post: Path Expected for Join! Nhibernate Error and can't seem to apply the same logic to my query. My User object has a UserGroup collection.
I understand that the query needs to reference entities within the object, but from what I'm seeing I am...
#NamedQuery(
name = "User.findByGroupId",
query =
"SELECT u FROM UserGroup ug " +
"INNER JOIN User u WHERE ug.group_id = :groupId ORDER BY u.lastname"
)
select u from UserGroup ug inner join ug.user u
where ug.group_id = :groupId
order by u.lastname
As a named query:
#NamedQuery(
name = "User.findByGroupId",
query =
"SELECT u FROM UserGroup ug " +
"INNER JOIN ug.user u WHERE ug.group_id = :groupId ORDER BY u.lastname"
)
Use paths in the HQL statement, from one entity to the other. See the Hibernate documentation on HQL and joins for details.
You need to name the entity that holds the association to User. For example,
... INNER JOIN ug.user u ...
That's the "path" the error message is complaining about -- path from UserGroup to User entity.
Hibernate relies on declarative JOINs, for which the join condition is declared in the mapping metadata. This is why it is impossible to construct the native SQL query without having the path.
You'll be better off using where clauses. Hibernate does not accept inner joins for tables where the PK/FK relationship is not there between Entities
do
SELECT s.first_name, s.surname, sd.telephone_number FROM Student s, StudentDetails sd WHERE s.id = sd.student_id
instead of
SELECT s.first_name, s.surname, sd.telephone_number FROM Student s INNER JOIN StudentDetails sd on s.id = sd.student_id
The latter will only work if Student's id (s.id) is referenced as FK on StudentDetails (sd.student_id)) table design / erd

Categories

Resources