with-clause not allowed on fetched associations - mysql

I have a name query like the one below - but keep getting an error from Hibernate that it will not allow my 'with'-clause since I'm doing join fetch.
I need to do join fetch - because it there is a related item then I wan't it to be present on the object.
#NamedQuery(name = "Item.findItem",
query = "SELECT DISTINCT(c) FROM Item c " +
"JOIN FETCH c.storeRelations as childStoreRelation " +
"LEFT JOIN FETCH c.relatedItems as relatedRelations WITH relatedRelations.store.id = childStoreRelation.store.id " +
"WHERE c.id = :itemId " +
"AND childStoreRelation.store.id = :storeId " +
"AND childStoreRelation.deleted <> 'Y' " +
"ORDER BY c.partnumber "),
Suggestion would be to move the 'with' part to my where clause - but this will cause invalid results.
Consider item A which might have to items related to it - but for some stores the relations are not valid.
If put in where clause then the store without relations will not shown the main item, since SQL will be build by Hibernate so it requires that if any relations exist, then they must be valid for the store - otherwise nothing is fetched :-(
So the classic fix found many places (store.id is null OR store.id = :storeId) will not work.
Does someone have another work around?
I'm running Hibernate 4.3.11
Thanks in advance

You cannot use LEFT JOIN FETCH with clause.
Please remove WITH clause and move them to WHERE clause.
It should like this:
#NamedQuery(name = "Item.findItem",
query = "SELECT DISTINCT(c) FROM Item c " +
"JOIN FETCH c.storeRelations as childStoreRelation " +
"LEFT JOIN FETCH c.relatedItems as relatedRelations " +
"WHERE c.id = :itemId " +
"AND relatedRelations.store.id = childStoreRelation.store.id" +
"AND childStoreRelation.store.id = :storeId " +
"AND childStoreRelation.deleted <> 'Y' " +
"ORDER BY c.partnumber "),

You need the ON keyword rather than the WITH keyword.

Related

MySQL Native Query not working in Spring Data JPA. What could I be doing wrong?

For some reasons my query is running perfectly in MySQL WorkBench but when added to the repository I am getting syntax error
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'as e1, profile_history as e2 WHERE e2.profile_id =
e1.profile_id and' at line 1.
#Query(value = "( SELECT e2.* "
+ " FROM (select ph1.profile_id, max(ph1.last_updated_on) as last_updated_on2 "
+ " FROM profile_history as ph1 "
+ " GROUP BY ph1.profile_id ) as e1, profile_history as e2 "
+ " WHERE e2.profile_id = e1.profile_id and e2.last_updated_on = e1.last_updated_on2 )", nativeQuery = true)
Page<ProfileHistory> getAllProfileHistoryByLastestRow(Pageable paging);
Honestly expecting to get a db hit without any error and retrieve results.
Maybe you need to specify dialect in the properties file. Don’t know your MySQL version, so can’t give you concrete example, but it should be something like this:
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
I figured out the issue after fighting for 02 days. The jdbc driver is not interpreting the query correctly. I had to escape the columns and tables in the native query. Normally I shouldn't have to do this.
#Query(value = " SELECT `e2`.`*` "
+ " FROM (select `eph1`.`employee_id`, max(`eph1`.`last_updated_on`) as `last_updated_on2` "
+ " FROM `employee_profile_history` `eph1` "
+ " GROUP BY `eph1`.`employee_id` ) `e1`, `employee_profile_history` `e2` "
+ " WHERE (`e2`.`employee_id` = `e1`.`employee_id` and `e2`.`last_updated_on` = `e1`.`last_updated_on2` )",
countQuery = "SELECT distinct count(*) FROM `employee_profile_history`",
nativeQuery = true)

Is it posible to have 2 Select statements with 2 different outputs in 1 query?

So I'm using MS Access to have users access a mysql database. I don't use linked tables rather connect to the database using ODBC DAO connections.
I'm generating a report which at the bottom gives the balance of the account. So far in my query I have been able to get all the data I need from the database except for the balance. Reason is that all the data I pull from database is filtered by a where statement between two dates and a company id. For the balance however I need another set of results giving me the sum of a whole column.
Reason I need to put this on a single sql query is because I will then pass this query to the recordsource of the report thus I cant use two queries.
I tried to use UNION but it doesnt work since I'm using a continuous form to show all results it creates more rows to fit for the second select statement.
This works as intended.
SELECT tbl10prepago.NumeroFactura, tbl10prepago.Fecha, tbl12vehiculosprepago.Tablilla, tbl11empleadosprepago.NombreEmpleado, tbl10prepago.Litros, tbl10prepago.CostoLitro, tbl10prepago.CantidadDinero, tbl13companiasprepago.NombreCompania, tbl13companiasprepago.Concepto, tbl5localidades.NombreLocalidad, tbl5localidades.DireccionPostal, tbl5localidades.Telefono
FROM (tbl10prepago INNER JOIN tbl12vehiculosprepago ON tbl10prepago.IdVehiculo = tbl12vehiculosprepago.ID)
INNER JOIN tbl11empleadosprepago ON tbl10prepago.IdEmpleado = tbl11empleadosprepago.ID
INNER JOIN tbl13companiasprepago ON tbl10prepago.CompaniaID = tbl13companiasprepago.ID
INNER JOIN tbl5localidades ON tbl13companiasprepago.LocalidadServicio = tbl5localidades.ID
WHERE tbl10prepago.Fecha BETWEEN '" & Format(Me.Text40, "yyyy-MM-dd HH:mm:ss") & "' AND '" & Format(Me.Text42, "yyyy-MM-dd HH:mm:ss") & "'
AND tbl10prepago.CompaniaID = " & Me.Combo34.Column(0) & "
ORDER BY tbl10prepago.Fecha;
What I need to add is this:
SELECT SUM(tbl14pagoprepago.pago) as [BALANCE]
FROM tbl14pagoprepago
WHERE tbl14pagoprepago.IDCompania = " & Me.Combo34.Column(0) & "
And not add it to the first Select results or filter by date also.
Thank you all in advance!
union will only work if you have same number of columns. What I can think of is you can add this balance field as new column.
SELECT tbl10prepago.NumeroFactura, tbl10prepago.Fecha, tbl12vehiculosprepago.Tablilla, tbl11empleadosprepago.NombreEmpleado, tbl10prepago.Litros, tbl10prepago.CostoLitro, tbl10prepago.CantidadDinero, tbl13companiasprepago.NombreCompania, tbl13companiasprepago.Concepto, tbl5localidades.NombreLocalidad, tbl5localidades.DireccionPostal, tbl5localidades.Telefono,
(SELECT SUM(tbl14pagoprepago.pago) FROM tbl14pagoprepago
WHERE tbl14pagoprepago.IDCompania = " & Me.Combo34.Column(0) & ") as [Balance]
FROM (tbl10prepago INNER JOIN tbl12vehiculosprepago ON tbl10prepago.IdVehiculo = tbl12vehiculosprepago.ID)
INNER JOIN tbl11empleadosprepago ON tbl10prepago.IdEmpleado = tbl11empleadosprepago.ID
INNER JOIN tbl13companiasprepago ON tbl10prepago.CompaniaID = tbl13companiasprepago.ID
INNER JOIN tbl5localidades ON tbl13companiasprepago.LocalidadServicio = tbl5localidades.ID
WHERE tbl10prepago.Fecha BETWEEN '" & Format(Me.Text40, "yyyy-MM-dd HH:mm:ss") & "' AND '" & Format(Me.Text42, "yyyy-MM-dd HH:mm:ss") & "'
AND tbl10prepago.CompaniaID = " & Me.Combo34.Column(0) & "
ORDER BY tbl10prepago.Fecha;

Using a Variable in LEFT JOIN

I'm trying to create a single query that returns a result if the id is found in either Result1 or Result2, but also searches for that ID in another table to return the 'skill.'
The query is in a loop so the ID changes. How can I change the query below to utilize the variable ID to match something in a given table column?
query = "SELECT "
"a.Item1, a.Item2, a.Result1, a.Result2, b.skill "
"FROM formulas AS a "
"LEFT JOIN skills AS b "
"USING (%u AS Id) "
"WHERE Type != 0 AND Result1 = %u OR Result2 = %u;";
Area of concern is: USING (%u AS Id)
(Edit: Cleaned up code for readability)
Nevermind, I figured it out...I just used 'ON'...
query = "SELECT "
"a.Item1, a.Item2, a.Result1, a.Result2, b.skill "
"FROM formulas AS a "
"LEFT JOIN skills AS b "
"ON (Id = %u) "
"WHERE Type != 0 AND Result1 = %u OR Result2 = %u;";

MS ACCESS Subselect “At most one record can be returned by this subquery.”

Could anybody explains me why this subquery is returning “At most one record can be returned by this subquery.”?
(SELECT TOP 1 J.observacao " +
" FROM tblPendenciaHistorico J " +
" INNER JOIN tblPendenciaPendenciaHistorico JH " +
" ON J.historicoId = JH.pendenciaHistoricoId " +
" WHERE JH.pendenciaId = P.pendenciaId " +
" ORDER BY J.data DESC) AS historicoStatus"
It seems that TOP 1 does not actually limit the result set to 1 result. That is due because Access select by matches which means that it will return 1 distinct row. So if two rows are identical, they are counted as 1 match and both will be returned. Reference. To fix this problem, you will have to include another field in your query that will make each row unique.

Complex JPQL ORDER statement

I'm trying to write a fairly complex JPQL statement that sorts results based on a value in another table. I know what the MySQL would look like, but I need help turning it into JPQL. Here's the equivalent SQL:
SELECT o.* FROM Observation o
LEFT JOIN Obs_Event p
ON p.Event_ID = o.Event_ID
LEFT JOIN Event_Set ppp
ON ppp.Event_ID = o.Event_ID AND ppp.Event_Set_ID = o.Event_Set_ID
WHERE o.Individual_ID = <some id>
AND o.Observation_Date = <a date value>
ORDER BY ppp.Seq_Num ASC
Any help on how to do this would be much appreciated. Specifically I seem to having trouble with this part:
ON ppp.Event_ID = o.Event_ID AND ppp.Event_Set_ID = o.Event_Set_ID
So, far I've tried this:
Query q= em.createQuery("select o " +
" from Observation as o " +
" join o.eventID p" +
" join p.eventSetCollection ppp " +
" where o.individualID = :indiv " +
" AND o.observationDate = :d " +
" AND o.eventID = ppp.event " +
"";
If I try to add something like
WHERE ...
AND o.eventSetID = ppp.eventSet
... it simply doesn't work. If I look at the generated SQL, it looks like ppp.eventSet is simply ignored.
Suggestions?
So, first thanks to the poster that commented, asking for my entity relationships. That forced me to take a closer look at things and realize what was wrong.
As it turns out, back when I was even worse at JPA than I am now, I set the o.eventID property to an actual Integer, as in the primary key of the record/object, instead of an actual object. Hence, in the JPQL above, I'm actually trying to map an object to an integer in the following statement:
AND o.eventID = ppp.event
turns out the correct statement is:
Query q= em.createQuery("select o " +
" from Observation as o " +
" join o.eventID p" +
" join p.eventSetCollection ppp " +
" where o.individualID = :indiv " +
" AND o.observationDate = :d " +
" AND o.eventID= ppp.event.eventID" +
" order by ppp.seqNum ASC" +
"");
This works in a pinch, although I should eventually change that relationship in the Observation class to actually go to an object.