HQL query with map in java - java

How to create HQL query "select new map(A.a1, B.b1) from A left join B on A.a2=B.b2" where B could not exist? Now it returns correct result only when B exists

Sorry. It was my fault. Incorrect condition in query: " where B.b3 = smth"

Related

QueryDSL order by subquery count

I want to implement the following SQL query with QueryDSL:
SELECT
*
FROM
a
ORDER BY (
SELECT
COUNT(*)
FROM
b
WHERE
b.a_id = a.id
AND b.c = 1) DESC
If I omit the criteria "b.c = 1", it's quite easy:
selectFrom(a).orderBy(a.bs.size().desc());
But I can't find a way (simple or not) to include a criteria in the subquery.
I want my QueryDSL query to return a List<A> and not Tuple, if possible.
Thanks in advance !

HQL merge two typedqueries

I have written two hibernate queries:
TypedQuery q = em.createQuery("SELECT user.id FROM TableOne AS user WHERE ...", Long.class);
TypedQuery q = em.createQuery("SELECT link.user_id FROM TableTwo AS link WHERE ...", Long.class);
Now, how do I merge these two queries? My return type has to be TypedQuery
the UNION statement not work on Hibernate.
So you can:
Execute first query and put in a list;
Execute second query and put in a list;
Put the result of first and second list in a unique list.
If you want to delete the duplicated value, you must do programmatically.
Completely copying answer from https://stackoverflow.com/a/3940445/929701:
You could use id in (select id from ...) or id in (select id from ...)
e.g. instead of non-working
from Person p where p.name="Joe"
union
from Person p join p.children c where c.name="Joe"
you could do
from Person p
where p.id in (select p1.id from Person p1 where p1.name="Joe")
or p.id in (select p2.id from Person p2 join p2.children c where c.name="Joe");
At least using MySQL, you will run into performance problems with the later though. It's sometimes easier to do a poor man's join on two queries instead:
// use set for uniqueness
Set<Person> people = new HashSet<Person>((List<Person>) query1.list());
people.addAll((List<Person>) query2.list());
return new ArrayList<Person>(people);
It's often better to do two simple queries than one complex one.

How to create a JPA query with LEFT OUTER JOIN

I am starting to learn JPA, and have implemented an example with JPA query, based on the following native SQL that I tested in SQL Server:
SELECT f.StudentID, f.Name, f.Age, f.Class1, f.Class2
FROM Student f
LEFT OUTER JOIN ClassTbl s ON s.ClassID = f.Class1 OR s.ClassID = f.Class2
WHERE s.ClassName = 'abc'
From the above SQL I have constructed the following JPQL query:
SELECT f FROM Student f LEFT JOIN f.Class1 s;
As you can see, I still lack the condition OR s.ClassID = f.Class2 from my original query. My question is, how can I put it into my JPQL?
Write this;
SELECT f from Student f LEFT JOIN f.classTbls s WHERE s.ClassName = 'abc'
Because your Student entity has One To Many relationship with ClassTbl entity.
If you have entities A and B without any relation between them and there is strictly 0 or 1 B for each A, you could do:
select a, (select b from B b where b.joinProperty = a.joinProperty) from A a
This would give you an Object[]{a,b} for a single result or List<Object[]{a,b}> for multiple results.
Normally the ON clause comes from the mapping's join columns, but the JPA 2.1 draft allows for additional conditions in a new ON clause.
See,
http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Basic_JPA_Development/Querying/JPQL#ON
Please see :
public interface YourDBRepository extends JpaRepository<Employee, Long> {
#Query("select new com.mypackage.myDTO(dep.empCode, dep.empName, em.EmployeeCode, em.EmployeeName) \n" +
"from Department dep\n" +
"left join Employee em\n" +
"on dep.DepartmentCode = em.DepartmentCode") // this is JPQL so use classnames
List<myDTO> getDeptEmployeeList();
}
You can also use CrudRepository and include #JoinColumn with FK table class in PK table class and have List return list and then do find operation to achieve the same.
In Department entity class:
#OneToMany
#Fetch(FetchMode.JOIN)
#JoinColumn(name="DEPT_CODE")
private List<Employee> employees;
CriteriaBuilder is yet another option.

Hibernate left join fetch - get only an ID list of the first table

I have the following HQL query which works fine, however it returns a list of full FooD objects. I only need the ID of the FooD objects as I need to have faster query. Please not that in Hibernate mappings, FooD has a many-to-one relationship with FooB.
hqlQuery = "from FooD d left join fetch d.bill where d.ts < :ts"
I have then tried to get only the ID using the same kind of HQL query:
hqlQuery = "SELECT d.id from FooD d left join fetch d.bill where d.ts < :ts"
I got a "query specified join fetching, but the owner of the fetched association was not present in the select list".
I have then converted the query to regular Oracle SQL to get only FooD.ID:
sqlQuery = "SELECT d.id from FooD d LEFT OUTER JOIN FooB b on d.foodId=b.id where d.ts < :ts"
I have then mapped FooD and FooB objects like this:
sqlQuery.addEntity(FooD.class);
sqlQuery.addEntity(FooB.class);
and then get the resulting list by calling:
hSession.createSQLQuery(sql).setTimestamp("ts", ts).list();
But got the following error: "unexpected token: on near line 1".
Does someone know how to do get only the ID of FooD when doing a left outer join on FooB using Hibernate?
Update:
I didn't test it, but this should do the trick
SELECT d.id from FooD d inner join d.bill where d.ts < :ts
when you add LEFT you make it an outer join implicitly, and there is no need to initialize bill if all you need is to join by keys
Hibernate requires the object to be in the select clause to do any eager join fetches on it
But since you have no select or where clauses on d.bill, why do you need to fetch it anyway?
If all you need is the id, why not do this, there is no reason for the redundant join:
hqlQuery = "SELECT d.id from FooD d where d.ts < :ts"

JPA and JPQL: NoResultException when selecting from multiple tables where one value is null

I'm using Java EE 6 and query a database using JPA's javax.persistence.Entitymanager. I have a JPQL query code snippet that looks like something like this:
Query query = entityManager.createQuery("
select A.propertyX, B.propertyY, C.propertyZ
from TableA A, TableB B, TableC C
where A.id = :id and B.id = A.id and C.type = B.type
");
query.setParameter("id", id);
Object[] result = (Object[]) query.getSingleResult();
Where propertyX/Y/X all are references to other entities. In my case, a matching row from TableA, TableB, and TableC all exist. For the matching rows, TableA.propertyX and TableB.propertyY hold values whereas TableC.propertyZ is null (and non-required).
I expect this to execute and return an Object[] array with values for the first two elements (propertyX and propertyY) and null for the third element (propertyZ).
However, when propertyZ is null, a NoResultException is thrown. If I change the data so that propertyZ is not null, the query executes and returns a value.
Is this expected JPQL behavior?
How can I ensure that my query will behave as I originally expected?
The obvious work-around is to select the entire root entity than any sub-property, e.g. 'C' rather than 'C.propertyZ', and then get the property out of the entity object. However, I'd like for this to work as I expect it to without doing so.
If, for a given row in A and B, there is a row in C where C.type = B.type, but the propertyZ column for that row is null, then you are right that your query should return a record.
However if for that given row in A and B, there is no matching row in C where C.type = B.type, then your query will return no result. This has nothing to do with JPQL, but with SQL
If you want the latter case to still return a record with null in the propertyZ field, you need to use OUTER JOINs
HTH

Categories