Left_Join on same tables in Hibernate Criteria API - java

I have a table and a class marked as #Entity with
#Table(name="Employee")
It has two fields, Id and Name
i want to do left join on same table like,
Select t2.name, count(*)
from Employee t1 left join Employee t2 on t1.Id = t2.Id
where t1.Name = 'asd'
group by t2.Name

I had a workaround, I converted that query into sub query
Select EmployeeID From Employee
Where ManagerID in (Select EmployeeID where performance >= 4 )
And used DetachedCriteria and i got it worked. But this will reduce my performance. SO i will try your method and see if i can get it worked
Ref
https://forum.hibernate.org/viewtopic.php?p=2389790

Related

How to write "JPQL" query with "IN" between SELECTs?

I wrote this JPQL query and expect a result as List<Question>:
#Query("SELECT q FROM Question q WHERE q.id IN (SELECT qc.questions FROM QCard qc WHERE qc.id IN (SELECT ct.qCards FROM CTest ct WHERE ct.id=:id))")
These are my classes:
class CTest {
id, List<QCard>
}
class QCard{
id, List<Question>
}
class Question{
id
}
I expected all questions as return for given CTest.id.
But I got a compiler-error with message:
SQLSyntaxErrorException
I tried use ":" before "select" words but it had not helped.
What is wrong?
Test your SQL query in an SQL-client (e.g. Squirrel, DbVisualizer, etc.).
Assuming your foreign keys are named:
question_id in table QCard
card_id in table CTest
you could have an SQL with subselects like:
SELECT q.id
FROM Question q
WHERE q.id IN (
SELECT qc.question_id
FROM QCard qc
WHERE qc.id IN (
SELECT ct.card_id
FROM CTest ct
WHERE ct.id = 1 -- example test id
)
)
Does it return the expected result or are there syntax errors?
Then subsequently replace your subselects by JOINs.
Question and Cards
SELECT q.id, c.id
FROM Question q
JOIN QCard c ON c.question_id = q.id
Cards and Tests
SELECT c.id, t.id
FROM QCard c
JOIN CTest t ON t.card_id = c.id
All together
SELECT q.id, c.id, t.id
FROM Question q
JOIN QCard c ON c.question_id = q.id
JOIN CTest t ON t.card_id = c.id
Note: add WHERE clauses like WHERE t.id = 1 if needed.
Experiment with the FROM/JOIN order as it makes sense.
Then translate the running SQL query to JPQL. For example:
#Query("SELECT q"
+ " FROM CTest test"
// a test has many cards (1:n)
+ " JOIN QCard card ON card.id = test.card_id" // associated cards
// a card has many questions (1:n)
+ " JOIN Question q ON q.id = card.question_id" // associated questions
+ " WHERE test.id = :id")
public List<Question> findQuestionsByTestId(String id);
List<Question> findByIdIn(List<Long> idList); //In repository
or
String qlString = "select i from Item i where i.name IN :names";
Query q = em.createQuery(qlString, Item.class);
List<String> names = Arrays.asList("foo", "bar");
q.setParameter("names", names);
List<Item> actual = q.getResultList();
I did those example in my past work, check it, tnx
In your existing query, in inner queries you are selecting entities and checking IN against Id, which will definitely won't work. As you can't complete entry with the Id.
As you haven't shared your complete entity structure, assuming that you have two way relationship declared correctly in entities, here I am placing a reference query which uses the join:
#Query("SELECT q FROM Question q JOIN q.qCard qc WHERE q.qCardId = qc.id AND qc.cTestId = :id")
Where qCardId is the foreign key reference of QCard entity in Question entity and cTestId is the foreign key reference of CTest entity in QCard entity.
You can use this for your reference to update your query with joins.

For each order without invoice

i solve this task with 2 native query but want to solve this with one native query maybe will you show me the way if possible.
it's my first query:
select o.id as id,o.date as date,o.customer_id_id as customerId
from orders o left outer join
invoice i
on o.id = i.order_id_id
where i.order_id_id is null
intersect
select o.id as id,o.date as date,o.customer_id_id as customerId
from detail d join
orders o
on o.id = d.order_id_id
it's my second query and i use from first query o.id it's mean ?1=o.id:
select sum(d.quantity*p.price)
from product p join
detail d
on p.id=d.product_id_id
where d.order_id_id=?1
it is grafic of project
enter image description here
text of task:For each order without invoice, list its ID, the date it was placed and the total price of the
products in its detail, taking into account the quantity of each ordered product and its unit
price. Orders without detail must not be included in the answers.
If I understand correctly, this is an aggregation query after joining three tables (orders, detail, product). You can use NOT EXISTS or LEFT JOIN/WHERE to filter out the orders with no invoices:
select o.id, o.date, o.customer_id_id as customer_id,
sum(d.quantity*p.price)
from orders o join
detail d
on o.id = d.order_id_id join
product p
on p.id = d.product_id_id
where not exists (select 1
from invoices i
where o.id = i.order_id_id
)
group by o.id, o.date, o.customer_id_id;

How to join two Criteria Queries

I have a query that I want to make Criteria Query
select u.email, st.total_amount, st.company_total from users u
join (select user_id, SUM(balance) as total_amount,SUM(company_count) as company_total from subscription s
where s.is_active = 0
group by user_id) st on u.id = st.user_id
where u.is_active = 0
order by st.company_total
I have already made 1 criteria Query
CriteriaQuery<UserImpl> innerQuery = builder.createQuery(UserImpl.class);
Root<Subscription> subscriptionRoot = innerQuery.from(Subscription.class);
innerQuery.multiselect(subscriptionRoot.get("user").get("id"), builder.sum(subscriptionRoot.get("balance")),
builder.sum(subscriptionRoot.get("companyCount")));
I don't know how to make the outer query in spring hibernate JPA. Can some help.
Defining a JOIN clause is pretty simple. You first call the from method on your CriteriaQuery object to get a Root object. In the next step, you can call the join method to define your JOIN clause.
Following is example of Docs, you can manipulate it as per your example.
You can refer Hibernate docs for the join examples. following is sample code.
CriteriaQuery<String> q = cb.createQuery(String.class);
Root<Order> order = q.from(Order.class);
q.select(order.get("shippingAddress").<String>get("state"));
CriteriaQuery<Product> q2 = cb.createQuery(Product.class);
q2.select(q2.from(Order.class)
.join("items")
.<Item,Product>join("product"));
Docs to refer
Another quick example I found is listed below:
<Y> ListJoin<X, Y> join(ListAttribute<? super X, Y> list);
Quick example (assuming Employee has list of Tasks with many-to-many relation):
CriteriaQuery<Employee> query = criteriaBuilder.createQuery(Employee.class);
Root<Employee> employee = query.from(Employee.class);
ListJoin<Employee, Task> tasks = employee.join(Employee_.tasks);
query.select(employee)
.where(criteriaBuilder.equal(tasks.get(Task_.supervisor),
employee.get(Employee_.name)));
TypedQuery<Employee> typedQuery = entityManager.createQuery(query);
List<Employee> employees = typedQuery.getResultList();
Reference: here

Hibernate Criteria and DetachedCriteria concate Properties or fields

i have a criteria like
public ArrayList<Student>getStudentsWithPicture(final Student student)
{
final Criteria criteria = session.createCriteria(Student.class).add(and(prepareForSelect()));
criteria.add(Subqueries.gt(1L,getDetached);//the students with a less added picture...
return new ArrayList<Student>(criteria.list());
}
i need the students with a less a picture in the table Pictures but this Database is a legacy one
they store the pictures concatening some fields for the student entity
yes a quite weird
i want something like this
SQL
select
this_.ID as y0_,
this_.C01 as y1_,
this_.C02 as y2_,
this_.C03 as y3_
from
student_table this_
where
(
and this_.C11=true
and 1>=
(
select
count(*)
from
PICTURE_TABLE this_
where
(
this_.C03='concatening'+ this_.ID+ this_.C01+this_.C02+this_.C03//the fields of the student
)
)
)
this is just a understandable example the actual query is a lot worse...
as you can see i want the students with status='true' and they have a less one match on the PICTURE_TABLE but the field C03 from the table is created by concatening the fields of the Student which i have retrieve it as well...
my detached
public DetachedCriteria getWithDetachedMatchStudentWithPictures()
{
final String concatedFields = ...........how i accomplish this??????.................
final DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Pictures.class)
.add(equals("c03",concatedFields))
.setProjection(addProjection("id"))
.setResultTransformer(transformer(Pictures.class));
return detachedCriteria;
}
my question is.
can i concate the fields at runtime..?? using Criteria A.P.I
there is some approach?
thanks a lot
Yes, we can contact multiple columns run time in hibernate.
i have concat columns in my beloved query.
Query query = session.createQuery("SELECT DISTINCT f.fileid , f.filename, f.filetype , f.folderpath , max(f.version) from FileBean f GROUP BY concat(folderpath,filename,'.',filetype)");
result = query.list();

HQL nested subqueries

I have such domain: Country has cities, city has offices, offices has services. I need to find all countries with offices which provide specified service id. My current version is:
SELECT c FROM Country c
WHERE EXISTS(
SELECT ct FROM c.cities ct
WHERE EXISTS(
SELECT o FROM ct.offices o
WHERE EXISTS(
SELECT s.id FROM o.services s
WHERE s.id = :id
)
)
)
So, I'm new to HQL. What is best way to this? Is my version Ok? I was thinking about SELECT DISTINCT with LEFT JOIN too.
I don't think there is anything wrong with your query, but this might be more readable.
SELECT c FROM Country
WHERE EXISTS (
SELECT s.id FROM
c.cities ct
JOIN ct.offices o
JOIN o.services s
WHERE s.id = :id
)

Categories

Resources