Hibernate Criteria: hibernate left join without association - java

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.

Related

JOIN with multiple OR in HQL

Below is a SQL query with multiple joins and conditions which gives the desired output, I want to convert the below query to HQL
select * from customer c
join customer_geo_rel cg on c.id=cg.customer_id
join geography g on cg.geo_id=g.id
join geo_geo_hierarchy gghCluster on g.id = gghCluster.geo_id
join geo_geo_hierarchy gghDivision on gghCluster.geo_id = gghDivision.parent_geo_id
join role_data_rel rdr on gghCluster.geo_id = rdr.permission_data_id OR
gghDivision.parent_geo_id = rdr.permission_data_id OR
g.id=rdr.permission_data_id
What's the problem? HQL supports the ON clause for joins and if you use a very old version of Hibernate, you can use the WITH clause like e.g. .. join g.roleDataRelList rds on ...

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

How to rewrite sql statement to work with hibernate?

I'm using PostgreSQL in my java application without ORM. I want to go further and add Hibernate to my project. I have this sql query which I add to PreparedStatement() and it returns a number.
SELECT COUNT(pr.id) FROM prisoner pr
JOIN cell c ON c.id = pr.cell_id
JOIN prison p ON p.id = c.prison_id
WHERE p.id = ?
I'm new to Hibernate. How would you suggest me to rewrite this statement to work with Hibernate? Should I use HSQL, or criteria or query or something different ?
You can do it Either of following way.
1) Keep you query as it and use nativeSQL for hibernate.
hibernate native query, count
2) make model of all your join table and put hibernate query.

Spring data jpa + joining 2 tables

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.

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

Categories

Resources