Spring data jpa + joining 2 tables - java

I have 2 entity classes Product and ProductAltID with no #OnetoMany mapping defined between them.
I want to do something like this
select p from ProductAltid inner join Product pai
where p.id = pai.id
How can I achieve this?

Add this method to the ProductAltId repository (choosing that one because the query returns ProductAltIds):
#Query("select pai from ProductAltId as pai "
+ "where pai.id in (select p.id from Product as p)")
List<ProductAltId> findForAllProducts();
I switched the aliases around, they seem backward in your example.

Related

Hibernate Query Returning Duplicate results

I am trying to join 3 tables to get an output. Following are the tables
player_match(match_id,team_id,player_id)
player(player_id,name,......)
team(team_id,name......)
All the tables have equivalent classes assigned.
Following is the SQL query that I am running and getting the correct results.
select * from player_match M
inner join team T
on M.team_id = T.team_id
inner join player P
on P.player_id = M.player_id
where M.match_id = 335987;
I am running the following Named query in PlayerMatch java class. PlayerMatch class has Match and Team objects in it. Both of these objects are mapped #ManyToOne.
#NamedQuery(name="getMatchData",query="select PM from PlayerMatch PM "
+ "inner join Team T on PM.teamId = T.teamId "
+ "inner join Player P on PM.playerId = P.playerId "
+ "where PM.matchId = :matchID")
When I run the above hibernate query I get 22 results which is correct, but the contents of all the results are the same.
The SQL query that I have mentioned above returns 22 non duplicate rows.
I think I am messing up somewhere in the Hibernate query but can't figure out where.
Your HQL query is structured similarly to an SQL query. You shouldn't need to specify the 'on' conditions as they are derived from the hibernate schema.
See hibernate documentation for more info on hql joins:
http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html#queryhql-joins

one 2 many jpa qry with join

I am trying to use jpa with join to qry one to many entities
Entity Table Unit (one)
Entity Table Appartment (many)
I am using the following JPA
#Query("Select u from Unit u inner join u.appartmentList a " +
"where u.unitNumber IN :unitNumbers " +
"and a.appNumber= :appNumber")
Page findApt(#Param("unitNumbers") Collection<String> unitNumbers,
#Param("appNumber") Integer appNumber,
Pageable pageable);enter code here
I need to be able to get 2 appartments (one in each unit passed as unita,unitb).
if I do a GET for ../findStuff?unitNumbers=unita,unitb&appNumber=1
But I get all appartments in each unit instead, not just appNumber=1 in each unit.
Any idea on how to achieve this would be greatly appreciated
Thank you
You need to query on Appartment.
#Query("select a from Appartment a where" +
" a.appNumber= :appNumber and a.unit.unitNumber IN :unitNumbers"
If unit is lazy fetched, you may want to fetch it with the first query, so the query becomes:
#Query("select a from Appartment a join fetch a.unit where" +
" a.appNumber= :appNumber and a.unit.unitNumber IN :unitNumbers"

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")

Hibernate Criteria: hibernate left join without association

I am a Hibernate newbie and i have this below query. It is working as i expected. These two tables are not associated. Is there a way to get the same result by using Criteria API or how can i run this query via Hibernate ? Any help would be appreciated.
SELECT p.title, c.content
FROM posts p
LEFT JOIN comments c ON p.id = c.post_id
WHERE p.status = 'A' AND (p.title iLIKE '%r%' OR c.content iLIKE '%r%');
Criteria API needs a path between entities, so I'm not sure this join could be done using Criteria API. Better do it with HQL if you have Hibernate >= 5.1:
select p.title, c.content
from org.example.Posts p
left outer join org.example.Comments c
on p.id = c.id
where p.status = 'A' AND (lower(p.title) LIKE '%r%' OR lower(c.content) LIKE '%r%');
Still, you could stick to using SQL queries with Hibernate or better still, create association between Posts and Comments.

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