Get multiple entities from hibernate sql join - java

I have 4 table:
Orders(orderID, orderDate, orderItem (OneToMany))
OrderItem(id, order(manyToOne), book (manyToOne), quantity)
Book (id, title, cost)
User(id, username, password)
Here is my query in SQL:
String sql = "SELECT orders.id, book.title, orderitem.quantity
FROM orderitem INNER JOIN book ON book.id = orderitem.book_id INNER JOIN orders ON orders.id = orderitem.orders_id WHERE user_id = 1;
(user_id is the foreign key of User in Orders table)
(orders_id is the foreign key of Orders in OrderItem table)
List<OrderItem> orderBookInfo = (List<OrderItem>) session.createSQLQuery(sql); // returns List<Object[]> why?!
This query result comes from joining of 3 tables (Book, Order, OderItem)
And this is the result in table:
Question is how can i assign each result's column to it's corresponding properties?
For example:
orderBookInfo.order.id = (first location of orderBookInfo)
orderBookInfo.book.title = (second location of orderBookInfo)

You need to execute an Entity query instead. Assuming you already mapped the entities properly, this is how the HQL query would look like:
SELECT o
FROM orderitem oi
JOIN FETCH oi.book
JOIN FETCH oi.orders
JOIN FETCH oi.user u
WHERE u.id = 1;

Related

How select distinct value with pageable Spring data JPA?

I want to make a distinct select in my table with pagination, but it is claiming this error. Does anyone know how to solve it?
org.postgresql.util.PSQLException: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list
#Query(value = "SELECT DISTINCT budget.* FROM budget LEFT JOIN user_budget ON budget.id = user_budget.budget_id ORDER BY budget.created DESC, ?#{#pageable}",
countQuery = "SELECT DISTINCT count(*) FROM budget LEFT JOIN user_budget ON budget.id = user_budget.budget_id",
nativeQuery = true)
public Page<Budget> findAllByfilter(Pageable pageable);

SQL: Invalid column name eventhough column is there?

I have the following Spring Data Query:
#Query(value = "select * from person where person_id =?! and family_id not in (select related_person_id from relationships where related_family_id = ?1)", native query = true)
Person getPerson(String personId);
I am getting the error:
Caused by: java.sql.SQLException: Invalid column name
However, I know that all my column names for the two tables in my query are correct, what could ne causing this?
i don't know the structure of your data but your spring data query has many typos and errors, the standard query method should be:
#Query(value = "select * from person where person_id =?1 and family_id not in (select related_person_id from relationships where related_family_id = ?2)", nativeQuery = true);
Person findByPersonIdAndRelatedFamilyId(String personId, String relatedFamilyId);
also check your inner select query -I don't know the relation between family_id and related_person_id- but it should return a family_id column or an aliased column as family_id may be thats why you're receiving such error ..

Hibernate native sql join query

I have a problem with hibernate native sql join query. My query is below and works on Mysql db.
SELECT c.cart_id, u.name, u.surname, c.totalPrice
FROM sandbox.cart c JOIN
sandbox.user u
ON u.id = c.placedBy
I am using hibernate in code and encountered an exception
java.sql.SQLException: Column 'id' not found.
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1055)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:956)
com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
com.mysql.jdbc.ResultSetImpl.findColumn(ResultSetImpl.java:1093)
Query in code here
Session session = hibernateUtil.getSessionFactory().getCurrentSession();
SQLQuery query = session.createSQLQuery(ORDER_PER_USER_QUERY);
query.addEntity(OrderPerUser.class);
return query.list();
Table column name
Cart
| cart_id | placedBy | totalPrice
User
| id | email | name | surname
My mapped class is
#Entity
public class OrderPerUser {
#Id
private long id;
private String name;
private String surName;
private long cartId;
private double totalPrice; }
You need to remove the line:
query.addEntity(OrderPerUser.class);
After that, you need to rewrite the code and map your object manually, because your OrderPerUser is not an entity:
Session session = hibernateUtil.getSessionFactory().getCurrentSession();
SQLQuery query = session.createSQLQuery(ORDER_PER_USER_QUERY);
List<OrderPerUser> returnList new ArrayList<>();
for(Object[] row : query.list()){
OrderPerUser orderPerUserObj = new OrderPerUser();
oderPerUserObj.setCartId(Long.parseLong(row[0].toString()));
//put other properties here
returnList.add(orderPerUserObj);
}
return returnList;
Edit1: Now I see that you added the mapped class, but OrderPerUser should not be an entity in your case, but a regular DTO. An entity requires an ID, but you can't select the ID in this case, because OrderPerUser is not part of a table, it is just some selected data that you want in your memory and not in the database. So you should make your OrderPerUser a regular data transfer object.
Please read about entities, data transfer objects, data access objects to see what each object should do.
My guess is that your OrderPerUser class which you try to use for collecting the result is expecting a column with name id, and you have no such column in your query...
Try using the query:
SELECT u.id, c.cart_id, u.name, u.surname, c.totalPrice
FROM sandbox.cart c
JOIN sandbox.user u ON u.id = c.placedBy

complicated sql query returning empty result

My database looks like this
tickets table
-------------
ticket_id
title
description
department_id
status_id
priority_id
assignee_id
creator_id
departments table
------------------
dep_id
dep_name
status table
------------
status_id
status_name
priority table
---------------
pr_id
pr_name
users table
-----------
u_id
username
password
salt
email
firstName
lastName
department_id
userlevel_id
userlevels table
-----------------
ul_id
ul_name
I need to load all tickets given the asignee id. My query looks like this
SQLQuery q = q.createSQLQuery("SELECT t.*,d.*,s.*,p.*,u.*,a.* FROM tickets t, departments d, status s, priority p, users u, attachments a WHERE t.department_id=d.dep_id AND t.status_id=s.stat_id AND t.priority_id=p.pr_id AND t.assignee_id=u.u_id AND t.creator_id=u.u_id AND t.tick_id=a.ticket_id AND assignee_id=?");
q.setInt(0, some_valid_assignee_id);
List<Object> result = q.list();
But it's returning an empty object list. Can anyone point me in the right direction, thanks!!
In your query you have AND t.assignee_id = u.u_idand also AND t.creator_id = u.u_id. The only way that would return any records is if the assignee_id and creator_id were the same. I think what you really need to do is link to the users table twice like so:
SELECT t.*, d.*, s.*, p.*, u1.*, u2.*, a.*
FROM tickets t
INNER JOIN departments d ON t.department_id = d.dep_id
INNER JOIN status s ON t.status_id = s.stat_id
INNER JOIN priority p ON t.priority_id = p.pr_id
INNER JOIN users u1 ON t.assignee_id = u.u_id
INNER JOIN users u2 ON t.creator_id = u.u_id
INNER JOIN attachments a ON t.tick_id = a.ticket_id
WHERE assignee_id = ?
You should use proper join syntax . . . makes the query easier to read and to write.
However, I'm guessing that the problem is:
t.assignee_id = u.u_id AND t.creator_id = u.u_id
That would assume that
t.assignee_id = t.creator_id
Perhaps this never happens in your data.

Hibernate: Joining Criteria

Hi I need to do the following using Criteria
Select * from product pd, (Select productID pd1 from ... where ...) tpd1,
(Select productID pd2 from ... where ...) tpd2
where pd.productID = tpd1.pd1 and pd.productID = tpd1.pd2
May I know if it is possible?
The original SQL was using IN conditions
Select * from product pd where productID in (Select productID pd1 from ... where ...) and
productID in (Select productID pd2 from ... where ...)
but it takes too long to get the result, using the join SQL statement I was able to obtain my result faster.
any help?
Given you're using Hibernate, you may have to do something like this, which should work ok if the number of expected matches are relatively low:
select *
from product pd
where pd.productID in
(select productID
from product pd2
join tpd1 on (pd2.productID = tpd1.pd1)
join tpd2 on (pd2.productID = tpd2.pd2)
where tpd1....
and tpd2....
);
I assume there is a unique index on product.productID.
Alternatively, you could try the EXISTS formulation which may or may not work better than your original query:
select *
from product pd
where EXISTS
(select null from tpd1 where pd.productID = tpd1.pd1 and ...)
and EXISTS
(select null from tpd2 where pd.productID = tpd2.pd2 and ...)
;

Categories