hql request: order list result by manytomany collection property - java

I have a hql request which looks like:
select Distinct prof
from Professor as prof
left join fetch prof.students as stud
Professor and Student are in a manytomany relation.
I would like to order prof list by student's name.
I tried :
select Distinct prof
from Professor as prof
left join fetch prof.students as stud
order by prof.students.name
I got the error:
SEVERE: org.springframework.orm.hibernate3.HibernateQueryException: illegal attempt to dereference collection
I also tried:
select Distinct prof
from Professor as prof
left join fetch prof.students as stud
order by stud.name
I got the error:
SEVERE: org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query;
Is my order by clause possible? Or the hibernate mapping doesn't allow such request?

Remove the Distinct keyword from your query. Then, if you need to eliminate duplicates, use a ResultTransformer to consolidate the result set for you.
String hql = "select prof from Professor as prof left join fetch prof.students as stud order by stud.name";
Query query = session.createQuery(hql)
.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

Related

#Query for joining two tables

I am trying to join two entities in a third one using #Query method.
#Query("SELECT new com.concretepage.entity.DeptEmpDto(d.departmentId,d.departmentName,d.managerId,d.locationId,e.employeeId,e.firstName,e.lastName,e.phoneNumber,e.hireDate,e.jobId,e.salary,e.commissionPct) FROM Employee e INNER JOIN Department d")
List <DeptEmpDto> fetchEmpDeptDataInnerJoin();
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1.
I cannot understand where is my mistake.Any help will be appreciated :).
You missed the joining condition after joining tables using ON clause. So just change your query with this:
#Query("SELECT new com.concretepage.entity.DeptEmpDto(d.departmentId,d.departmentName,d.managerId,d.locationId,e.employeeId,e.firstName,e.lastName,e.phoneNumber,e.hireDate,e.jobId,e.salary,e.commissionPct) FROM Employee e INNER JOIN Department d on e.joining_column_from_table1=d.joining_column_from_table2")
Make sure to replace joining_column_from_table1 and
joining_column_from_table2 with your column names from table
Employee and Department respectively

Fetch data from 4 tables join together using hibernate query

I have 4 tables:
Teacher, Student, Course and their common join table TeacherStudentCourse.
The first three tables all have one to many relationship with the last table.
Here is a screenshot from my DB DataBase sample
Hence, for example, I should be able to get the desire Students by providing Teacher ID and Course ID.
I had previously asked a question on join table. Previous Question
And I do get the answer.
I was trying to improve based on the previous codes
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
List<Object> list = session.createQuery("select s from Student s join s.teacherStudentCourses tsc where tsc.teacher = :teacher and tsc.course = :course")
.setParameter("teacher", teacher)
.setParameter("course", course)
.list();
session.getTransaction().commit();
session.close();
But I do not seem to get it working after countless tries. Maybe the query just cannot create in that way? Any helps will be appreciated!
[UPDATE]
The error I get is:
org.hibernate.QueryException: could not resolve property: teacherStudentCourses of: model.Student [select s from model.Student s join s.teacherStudentCourses tsc where tsc.teacher = :teacher and tsc.course = :course]
Here tables are associated to each other with foreign key so all child table (teacher,cource,student) should have a parent type variable in their POJO.
Let this is "TeacherStudentCource tsc" in Student.class.
Now the query will be..
select s.studentId,s.name,s.gender,s.birthdate, from Student s inner join s.tsc b where b.teacherId=:tid and b.courceId=:cid;
Teacher ID=tid
Course ID =cid

HQL: Combine Left and Right Join

Good day everyone,
I'm currently struggeling with converting the following SQL to HQL:
SELECT
e.ID,
p.ID,
i.ID
FROM
ENTRY e
JOIN PERSON p ON e.FK_PERSON = p.ID
RIGHT JOIN IDENTITY i ON i.FK_PERSON = p.ID
WHERE
i.IS_MAIN_IDENTITY = 1
;
The way the DB is structured is:
One person may have one or more identities
One person has one main identity. The main identity is an identity with IS_MAIN_IDENTITY set to 1 (true)
One person may have zero or more entries
The purpose of this query is to build a screen collection which should display all entries, their owner (person) and their main identity (because only the identity contains a persons name, etc.)
My attempt so far to perform this query in HQL was:
select
entr,
pers,
iden
from
MEntry entr
join entr.entrPerson pers
right join iden.idenPerson
but this gave me the following exception:
java.lang.IllegalStateException: No data type for node:
org.hibernate.hql.internal.ast.tree.IdentNode
\-[IDENT] IdentNode: 'iden' {originalText=iden}
What am I doing wrong here? Or is there a even better way to write this query?
Thank you for your time in advance.
You need to write your SQL query like this:
SELECT
e.ID,
p.ID,
i.ID
FROM
PERSON p
INNER JOIN ENTRY e ON e.FK_PERSON = p.ID
INNER JOIN IDENTITY i ON i.FK_PERSON = p.ID
WHERE
i.IS_MAIN_IDENTITY = 1
and the HQL equivalent is:
select
p
from
Person p
join fetch p.entries e
join fetch p.identity
So you select only Persons but each Person also contains as Identity and a list of Entry entities. You can then access all the entries for each person on your UI.

Exception : org.hibernate.exception.SQLGrammerException and org.hibernate.exception.GenericJDBCEXception

This is HQL query :
SELECT COUNT(s)
FROM Site s JOIN s.topics t
INNER JOIN t.topicExpertAssignment tea
INNER JOIN tea.expert u
INNER JOIN u.userinfo info
WHERE tea.assignedBy.id = 1 AND s.createdBy = tea.expert.id
ORDER BY s.name
when i try to run this HQL query first time , it Generate org.hibernate.exception.SQLGrammerException: could not execute query exception and when i try to run again this query it generates org.hibernate.exception.GenericJDBCEXception: could not execute query exception. without COUNT() the query run successfully. how to resolve this exceptions and thanks in Advance.
Query is incorrect, because ORDER BY references to s.name, and s.name is not one of the items in select list.
Most likely correct solution is to remove ORDER BY s.name. It does not make too much sense to define order when result is one value.

HQL/SQL/Criteria to join-match all records in a given list while selecting all fields

I'm trying to write a HQL/Criteria/Native SQL query that will return all Employees that are assigned to a list of Projects. They must be assigned to all Projects in order to be selected.
An acceptable way of achieving this with native SQL can be found in the answer to this question: T-SQL - How to write query to get records that match ALL records in a many to many join:
SELECT e.id
FROM employee e
INNER JOIN proj_assignment a
ON e.id = a.emp_id and a.proj_id IN ([list of project ids])
GROUP BY e.id
HAVING COUNT(*) = [size of list of project ids]
However, I want to select all fields of Employee (e.*). It's not possible to define SQL grouping by all the columns(GROUP BY e.*), DISTINCT should be used instead. Is there a way to use DISTINCT altogether with COUNT(*) to achieve what I want?
I've also tried using HQL to perform this query. The Employee and ProjectAssignment classes don't have an association, so it's not possible to use Criteria to join them. I use a cross join because it's the way to perform a Join without association in HQL. So, my HQL looks like
select emp from Employee emp, ProjectAssignment pa
where emp.id = pa.empId and pa.paId IN :list
group by emp having count(*) = :listSize
However, due to a bug in Hibernate, GROUP BY entity does not work. The SQL it outputs is something like group by (emptable.id).
Subquerying the assignment table for each project (dynamically adding and exists (select 1 from proj_assignment pa where pa.emp_id=e.id and pa.proj_id = [anId]) for each project in the list) is not an acceptable option.
Is there a way to write this query properly, preferrably in HQL (in the end I want a List<Employee>), without modifying mappings and without explicitly selecting all columns in the native SQL ?
EDIT: I'm using Oracle 10g and hibernate-annotations-3.3.1.GA
How about:
select * from employee x where x.id in(
SELECT e.id
FROM employee e
INNER JOIN proj_assignment a
ON e.id = a.emp_id and a.proj_id IN ([list of project ids])
GROUP BY e.id
HAVING COUNT(*) = [size of list of project ids]
)
I've found an alternative way to achieve this in HQL, it's far more inefficient than what I'd like, (and than what is really possible without that nasty bug) but at least it works. It's better than repeating subselects for each project like
and exists (select 1 from project_assignment pa where pa.id = someId and pa.emp_id = e.id)
It consists of performing a self-join subquery in order to find out, for each of the Employees, how many of the projects in the list they are assigned to, and restrict results to only those that are in all of them.
select e
from Employee
where :listSize =
(select distinct count(*)
from Employee e2, ProjectAssignment pa
where
e2.id = pa.id_emp and
e.id = e2.id
and pa.proj_id IN :projectIdList
)

Categories