HQL not working "in" with multiple values - java

I have hibernate which goes something like this.
String queryString = "from MFunction as mFunction where mFunction.functionKey in "
+ "((select mRole.enterprise from MRole as mRole where mRole.roleKey=:role), "
+ "(select mRole2.project from MRole as mRole2 where mRole2.roleKey=:role ), "
+ "(select mRole3.technology from MRole as mRole3 where mRole3.roleKey=:role ))";
But the hibernate query takes in only the first value.
Hibernate: select mfunction0_.FunctionKey as Function1_73_, mfunction0_.`Add` as Add2_73_, mfunction0_.`Audit` as Audit3_73_, mfunction0_.ClientKey as ClientKey73_, mfunction0_.CreatedBy as CreatedBy73_, mfunction0_.CreatedTs as CreatedTs73_, mfunction0_.`Delete` as Delete7_73_, mfunction0_.`Edit` as Edit8_73_, mfunction0_.`Financial` as Financial9_73_, mfunction0_.FunctionName as Functio10_73_, mfunction0_.`General` as General11_73_, mfunction0_.Level as Level73_, mfunction0_.LevelKey as LevelKey73_, mfunction0_.LogicalDeleteTms as Logical14_73_, mfunction0_.UpdatedBy as UpdatedBy73_, mfunction0_.UpdatedTs as UpdatedTs73_, mfunction0_.`View` as View17_73_ from appanalytixdb.M_Function mfunction0_ where mfunction0_.FunctionKey in (select mrole1_.Enterprise from appanalytixdb.M_Role mrole1_ where mrole1_.RoleKey=?)
Hibernate version: 4.1.8.Final

Your problem is that you created a list of lists, and you should create a single list of functionkeys.
I see only 2 options:
Change one 'in' to 3 statements connected with or.
String queryString = "from MFunction as mFunction where mFunction.functionKey in (select mRole.enterprise from MRole as mRole where mRole.roleKey=:role) or mFunction.functionKey in (select mRole2.project from MRole as mRole2 where mRole2.roleKey=:role ) or mFunction.functionKey in (select mRole3.technology from MRole as mRole3 where mRole3.roleKey=:role )";
Best solution would be to preselect all projects,technologies,enterprise and union them together (to avoid duplicates). But hibernate does not yet support union, according to this post Hibernate Union alternatives.
If you have not so many entries in your tables, I would create a view, and used my query on it. Views can be quite cheap and easy to use in this scenarios.

Related

Hibernate Criteria with joins not generating correct SQL

I'm trying to execute a Criteria query but when I execute the code, the SQL only brings up company_synonym in the from clause, not the other two.
The mappings are:
Company has 1-to-Many CompanySynonyms
Company has 1-to-Many CompanyProductRoles
I want the query to return CompanySynonym objects, so I tried this:
Criteria criteria = session.createCriteria(CompanySynonym.class, "cs")
.createAlias("cs." + CompanySynonym.COMPANY, "cmp")
.createAlias("cmp." + Company.COMPANY_PRODUCT_ROLE, "cpr")
.add(Restrictions.eq("cs." + CompanySynonym.TYPE, "1234"))
.add(Restrictions.eq("cpr." + CompanyProductRole.PRODUCT_ID, Integer.valueOf(productId)))
.add(Restrictions.isNotNull("cpr." + CompanySynonym.Company_ID))
.add(Restrictions.eq("cpr." + CompanyProductRole.ROLE_CODE, "AB"));
And it generates this SQL:
select this_.company_syn_id_i as company1_0_0_, this_.company_id_i as company5_0_0_, this_.cmp_syn_end_d as cmp2_0_0_, this_.cmp_syn_type_cd_c as cmp3_0_0_, this_.cmp_syn_c as cmp4_0_0_
from product.dbo.company_synonym this_
where this_.cmp_syn_type_cd_c=?
and cpr1_.product_id_i=?
and cpr1_.company_id_i is not null
and cpr1_.role_cd_c=c
What am I missing or doing wrong here?

Number of characters in sql query result

I am using Spring 3.1.1 with Hibernate 4 and a MSSQL database. Finally, I have been able to query my database with joins in my table that returns the correct answers. Although, it seems that it does not return the entire strings of my messages, but cuts at 29/30 digits. Here is my query:
SQLQuery sql = this.getCurrentSession().createSQLQuery(
"SELECT event.id as eventid, CAST(event_type.type_name AS varchar) as eventtype, event.check_date, event.event_date, event.status, CAST(event_message.message AS varchar) as eventmessage " +
"FROM event_log event " +
"LEFT JOIN event_type " +
"ON (event.event_type_id = event_type.id) " +
"LEFT JOIN event_message " +
"ON (event.event_message_id = event_message.id) " +
"WHERE event.event_type_id = " + jobId +
"ORDER BY eventid");
The result can be:
4506 Database 2014-01-15 14:14:15.02 2014-01-15 14:14:15.02 false Database-connection cannot be
Where the columns are id, task_name, check_date, event_date, status and the message-string at the end. .
The result goes to a ArrayList<Object[]> where I read row[0] etc. to get the entities in the row. The string message gets cut after 29 digits, which is disturbing. Why does it cut the string and how can I fix this? In my database the string exists in it's full and is entitled 400 characters max.
I know this is probably not the best way to query my database, but it will do for my application since it works.
You are using varchar without a length. Never do this!
Replace:
CAST(event_type.type_name AS varchar)
With something like:
CAST(event_type.type_name AS varchar(255))
In some contexts, the default length is 32. In some it is 1. In general, though, always specify the length.
EDIT:
Actually, you probably don't even need the cast. Why not just have event_type.type_name in the select list?

JPA avoiding multiple subquery

I need a little help setting up my query. I don't want to have to make multiple selects to form basically the same sub-query if I can avoid it. In a nut shell, I have Objects called TimeSlot that are used to track several details. Those TimeSlot's are items that are paid on. When its time for the TimeSlot to submit for a reimbursement they are used to create a PayableTimeSlot. Before the TimeSlot can be paid I need to make sure it has not been paid already.
As it sits the following is my query:
#NamedQuery(
name = "TimeSlot.by.person.academy.id.by.contract.date",
query = "select distinct ts
from TimeSlot ts
join ts.invitedInstructors ii
join ts.academyClass ac
join ac.academy a
where ii.person.id = ?
and a.id = ?
and ts.schedule.startDateTime BETWEEN ? AND ?
and ts.id not in (select e.id from PayableTimeslot pts join pts.event e)
and ? not in (select e.claimant from PayableTimeslot pts join pts.event e)")
As you can see I am already selecting an element from the PayableTimeSot for the first not in. Is there a way to expand the sub-query into:
(select e.id, e.claimant from PayableTimeslot pts join pts.event e) I am just not sure how to check for multiple items not in the sub-query. By all means if there is a better attack of the problem than the way I am doing it let me know.
Unless you all think the multiple selects wont be a big deal... There will be on average 30-50 entry's a week into the table with each entry being copied (for an audit trail) upwards of 7-9 times.
Okay so after some thinking this is what I came up with. I was indeed trying to answer the problem in the wrong way... I was doing two sub querys when all I needed was a where on the first thus combining the two.
#NamedQuery(
name = "TimeSlot.by.person.academy.id.by.contract.date",
query = "select distinct ts "
+ "from TimeSlot ts "
+ "join ts.invitedInstructors ii "
+ "join ts.academyClass ac "
+ "join ac.academy a "
+ "where ii.person.id = ? "
+ "and a.id = ? "
+ "and ts.schedule.startDateTime BETWEEN ? AND ? "
+ "and ts.id not in (select e.id from PayableTimeslot pts join pts.event e where pts.claimant = ?)")

Complex SQL query to Hibernate HQL statement

Following SQL query:
select distinct hotel.country 'Country', hotel.id 'Hotel ID', hotel.Name'Name', room.id 'Room ID'
from room, stay, reservation, hotel
where
(stay.roomid = room.id)
and (stay.reservationid = reservation.id)
and (reservation.status != 'Booked' AND reservation.status != 'CheckedIn')
and (reservation.arrivaldate >= '2012-08-08')
and (reservation.leavedate <= '2012-08-15')
and (room.hotelid = hotel.id)
order by hotel.country, hotel.id, hotel.name, room.id asc
This will give me a list of available rooms per hotel per country. Now I have to put this in HQL, but I can't do so because of this:
Query query = session.createQuery("from room, stay, reservation, hotel where stay.roomid = room.id");
This doesn't work becuase stay.roomid is a Room object whereas room.id is just an integer. I'm pretty new to Hibernate/HQL and the reference manual didn't really bring me anywhere... How can I "convert" (scary word, I know this doesn't involve actual converting) this SLQ query to a HQL statement? Thanks.
UPDATE
Using a join result in the same problem
Query query = session.createQuery("" +
"from Stay stay " +
"join stay.ReservationID reservation " +
"join stay.RoomID room " +
"join room.HotelID hotel " +
"where (stay.RoomID = room.ID)");
I'm really missing something (probably very logical) here...
You haven't shown your entities, but, just as you would use joins in SQL, you need to use joins in HQL:
select ...
from Stay stay
join stay.reservation reservation
join stay.room room
join rom.hotel hotel
where (reservation.status != 'Booked' AND reservation.status != 'CheckedIn')
and (reservation.arrivaldate >= '2012-08-08')
and (reservation.leavedate <= '2012-08-15')
The Hibernate documentation has a whole chapter on HQL, and a section of this chapter about associations in HQL.

Delete query in mysql

I want to delete rows from multiple tables. I know the select query, but I need an exact delete query for all the columns that are defined below:
SELECT j.application_id,
j.first_name,
j.last_name,
c.description,
l.description,
p.description, " +
"j.email,
j.date_applied,
j.application_status,
j.dob, j.current_city, j.phone_mobile, j.phone_residence " +
"FROM jobapp.job_applications j,
jobapp.countries c,
jobapp.countries l ,
jobapp.job_locations p " +
"WHERE j.preferred_location = p.id
AND j.current_country = l.id
AND j.nationality = c.id "; //+
//"and application_status like ? and first_name like ? and last_name like ? and email like ?";
The query works fine using MySQL, but I need an delete query for the exact columns where the rows are get deleted...
delete statements are structured like:
DELETE FROM table WHERE condition.
you should replace condition with the primary key from you query above (if it is present) and reference each table one at a time.

Categories

Resources