JPA select using IN - java

Here is my select from the database:
SELECT * FROM testlogging.employees
where
EMPLOYEE_NO in (
select EMPLOYEES_EMPLOYEE_NO from testlogging.test_logging
where ID in (
select TEST_LOGGING_ID from testlogging.test_logging_detail
where APPROVAL_LEVELS_ID = '4'
)
)
How would i do this in JPA?
SELECT e FROM Employees e ???

If you're asking for the JPA INsyntax you would do this:
SELECT e FROM Employees e where e.employee_no IN :employeelist
as well ass
query.setParameter( "employeelist" , yourlist );
and of course build yourlist accordingly. If you don't really need to parameterize the inner queries, you can disregard this and just go the straight forward route.
Cheers,

Just in case you're using the JPA Criteria metamodel queries, the IN usage goes like this
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class);
Root<Pet> pet = cq.from(Pet.class);
cq.where(pet.get(Pet_.color).in("brown", "black"));
as stated at http://docs.oracle.com/javaee/6/tutorial/doc/gjivm.html

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 !

how to write with clause using criteria in hibernate

I have a query where i used WITH clause to generate results.
WITH employee AS (SELECT * FROM Employees)
SELECT * FROM employee WHERE ID < 20
UNION ALL
SELECT * FROM employee WHERE Sex = 'M'
Could you please any one let me know how to write this query in hibernate using criteria specially when with clause present in query.
First, you've dramatically over-complicated your SQL. Here's how your query should look in pure SQL:
SELECT * FROM Employees WHERE ID < 20 or Sex = 'M'
Next, assuming you have a Hibernate entity (let's call it Employee.java for now), your HQL equivalent would be:
from Employee e where e.id < 20 or e.sex = 'M'
To do it with a Criteria, you'd do the following:
final Criteria criteria = getSession().createCriteria(Employee.class);
criteria.add(Restrictions.or(
Restrictions.lt("id", 20),
Restrictions.eq("sex", "M")
)
);
criteria.list();

Java Hibernate Restcrition Criteria OR with DetachedCritera

Criteria criteria = session.createCriteria(TableA.class)
.add(Subqueries.propertyNotIn("id_a", DetachedCriteria.forClass(TableB.class)
.createAlias("id_a_from_tableB", "b")
setProjection(Property.forName("b.id_a"))));
I use this to get id_a from TableA if id_a is not in TableB. I need also get id_a if is in TableB but field "message" is not null.
I think this post can help you.
with criteria I think hibernate does not support UNION ALL but you
can use two criteria queries to get the expected result:
Criteria cr1 = session.createCriteria(Suppliers.class);
cr1.setProjection(Projections.projectionList()
.add( Projections.property("supplier_id"), "supplier_id" )
);
List results1 = cr1.list();
Criteria cr2 = session.createCriteria(Orders.class);
cr2.setProjection(Projections.projectionList()
.add( Projections.property("supplier_id"), "supplier_id" )
);
List results2 = cr2.list();
results1.add(results2);
List unionAllList = results1; //this is the expected result.
For example, you could add new criteria when you get from TableB if message is not null, and later just join two Java collections:
Criteria criteria1 = session.createCriteria(TableB.class)
.add( Restrictions.isNotNull("message")
P.S. Or I recommend using Criteria API from JPA2.1 (Chapter 6) instead of hibernate Criteria, because it's look like simple SQL and this solution is much more universally.

QueryDSL Window functions

How can I write a query using window functions and selecting all fields in QueryDSL?
In the docs there is an example like this:
query.from(employee)
.list(SQLExpressions.rowNumber()
.over()
.partitionBy(employee.name)
.orderBy(employee.id));
but I need to generate a query like:
SELECT * FROM
(SELECT employee.name, employee.id, row_number()
over(partition BY employee.name
ORDER BY employee.id)
FROM employee) AS sub
WHERE row_number = 1
And is it possible to do it with JPAQuery?
JPAQuery supports only the expressivity of JPQL, so window functions are not supported, but paging should work using
query.from(employee).orderBy(employee.id).limit(1)
In case you need to use window functions and you need employee.name and employee.id out this should work
NumberExpression<Long> rowNumber = SQLExpressions.rowNumber()
.over()
.partitionBy(employee.name)
.orderBy(employee.id).as("rowNumber");
query.select(employee.name, employee.id)
.from(SQLExpressions.select(employee.name, employee.id, rowNumber)
.from(employee).as(employee))
.where(Expressions.numberPath(Long.class, "rowNumber").eq(1L))
.fetch();
As written by #timo Window functions (rank, row_number) are not supported by JPQL (JPA 2.1 version) and hence by JPAQuery (QueryDsl Jpa 4.1.4).
You can however rewrite your query so that is does not use rank over():
select a.* from employees a
where
(
select count(*) from employees b
where
a.department = b.department and
a.salary <= b.salary
) <= 10
order by salary DESC
This is supported by JPAQuery, it probably goes like this.
final BooleanBuilder rankFilterBuilder =
new BooleanBuilder(employee.department.eq(employee2.department));
rankFilterBuilder.and(employee.salary.loe(employee2.salary));
query.from(employee)
.where(JPAExpressions.selectFrom(employee2)
.where(rankFilterBuilder)
.select(employee2.count())
.loe(10))
.orderBy(employee.salary);

Hibernate Criteria to find Duplicates

I want to get the duplicate entries. I want to use the query as criteria, for this i am using the below code.
SELECT * from A
WHERE field in (
SELECT field from A
GROUP BY field HAVING COUNT(field) > 1
);
The Hibernate mapping is like
#Entity
class A{
...
private String field;
...
}
How can I get list of A that have duplication in 'field' column?
You can pretty much translate your query one to one to HQL (warning: untested).
select A
from A a
where a.field in (
select ai.field
from A ai
group by ai.field -- assumes that by f you mean field
having count(a1.field) > 1
)
My own answer according prompted Anthony Accioly
final Criteria searchCriteria = session.createCriteria(A.class);
...
final DetachedCriteria d1 = DetachedCriteria.forClass(A.class);
d1.setProjection(Projections.count("field"));
d1.add(Restrictions.eqProperty("field", "AA.field"));
final DetachedCriteria d2 = DetachedCriteria.forClass(A.class, "AA");
d2.setProjection(Projections.projectionList()
.add(Projections.groupProperty("field")));
d2.add(Subqueries.lt(1L, d1));
criteria.add(Property.forName("field").in(d2));

Categories