Incomplete data while fetching through Named Query JPA2.0 - jpa

I have an entity named ReqestDetail and done association and mapping as below snippet:
#ManyToOne
#JoinColumn(name="STATUS_C")
private StatusCode statusCode;
//bi-directional many-to-one association to RequestAddressDetail
#OneToMany(mappedBy="requestDetail")
private List<RequestAddressDetail> addressDetails;
I have created below Named Query to fetch the details on the basis of address.
TypedQuery<RequestDetail> query = em.createQuery( "SELECT t FROM RequestDetail t" +
" LEFT JOIN t.employeeDetail e " +
" LEFT JOIN t.addressDetails ao " +
" LEFT JOIN t.addressDetails ad " +
" WHERE (e.employeeI IN ( :employeeIds ) ) AND " +
" (ao.postI = :postO AND ao.addressTypeC = :addressTypeO " +
" AND ad.postI = :PostD AND ad.addressTypeC = :addressTypeD )" ,
RequestDetail.class );
However, when I call query.getResultList(), it is only giving me data of RequestDetail Entity but not of the mapping joins I have mentioned in that entity.
Please advise...

why do you think it should give you some joined objects? Your candidate for the query is RequestDetail, so it gives that. If you did a JOIN FETCH then you can fetch other fields, but you haven't done that (so change those LEFT JOIN to LEFT JOIN FETCH) - a JOIN (without FETCH) is simply a convenience way of forming the query.. Alternatively you could set the entity graph to fetch, or set the fetch on the field itself if you wanted those fetching

Related

Page result returns different values than the generated SQL

After upgrading to spring-data-jpa 3.0.0 a JPQL query that uses Pageable is returning less elements than expected.
I executed the generated SQL from the console and that returns the correct number of elements.
I don't see a count SQL query being generated when using spring-data-jpa 3.0.0
JPQL Query:
#query(value = "select fsd from FeeScheduleDrugEntity fsd "
+ "left join DrugNdcEntity ndc on fsd.drug.id = ndc.drug.id and fsd.drug.noc = true "
+ "left join FeeScheduleSourceEntity fsse on fsse.id = fsd.drugFeeScheduleSource.id "
+ "where fsd.feeSchedule.id = :feeScheduleId ")
Generated SQL:
select f1_0.fee_schedule_drug_id,
f1_0.allowable_per_billing_unit,
f1_0.fee_schedule_drug_source,
f1_0.created_at,
f1_0.created_by,
f1_0.drug_id,
f1_0.fee_schedule_item_source_id,
f1_0.fee_schedule_id,
f1_0.modified_at,
f1_0.modified_by
from core.fee_schedule_drug f1_0
join core.drug d2_0 on d2_0.drug_id = f1_0.drug_id
left join core.drug_ndc d1_0 on f1_0.drug_id = d1_0.drug_id and d2_0.is_noc = true
left join core.fee_schedule_item_source f2_0
on f2_0.fee_schedule_item_source_id = f1_0.fee_schedule_item_source_id
where f1_0.fee_schedule_id=?
order by d1_0.ndc asc
offset ? rows fetch first ? rows only
I am expecting the same number of results from my query

How to make a join with ON in jpa? ( Spring Data Jpa 1.4 )

I have this query, which I have tried in SQL and it goes perfectly
#Query("SELECT new es.abacor.elser.commons.empleado.EmpleadoList("+
"empleado.id,persona.nombre,persona.apellido1,persona.apellido2,persona.dni,persona.email)" +
" FROM rrhh.empleado as empleado" +
" INNER JOIN commons.persona AS persona ON empleado.persona_comun = persona.id" +
" WHERE" +
" empleado.persona_comun is not null" +
" and empleado.borrador = false" +
" and empleado.deleted is null" +
" and empleado.fecha_fin_contrato is null" +
" order by persona.nombre,persona.apellido1,persona.apellido2 asc")
public List<EmpleadoList> allEmpleadosList();
But I get the following error when executing within my project
Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: ON near line 1, column 217 [SELECT new es.abacor.elser.commons.empleado.EmpleadoList(empleado.id,persona.nombre,persona.apellido1,persona.apellido2,persona.dni,persona.email) FROM rrhh.empleado as empleado INNER JOIN commons.persona AS persona ON empleado.persona_comun = persona.id WHERE empleado.persona_comun is not null and empleado.borrador = false and empleado.deleted is null and empleado.fecha_fin_contrato is null order by persona.nombre,persona.apellido1,persona.apellido2 asc]
Someone knows what I'm doing wrong, I do not know what to do anymore.
JPA doesn't work on tables, it works on objects. If you want to use native queries you have to add nativeQuery=true to the Definition:
#Query(nativeQuery=true, <SQL-Statement>)
otherwise the ON clasue will be generated from the annotations in your entities

Spring Data JPA sort column not in table/entity

I have query like that:
#Query(value = "SELECT new com.domain.ActivityStatistic( " +
"adm.id, " +
"adm.fullName, " +
"COUNT(CASE WHEN (act.action = 'APPROVE') THEN act.action END) AS approved, " +
"max(act.actionTime) AS lastActionTime) " +
"FROM Actions act, Admins adm LEFT JOIN adm.group gr " +
"WHERE adm.id = act.adminId AND act.actionTime BETWEEN ?1 AND ?2 AND gr.id = ?3 " +
"GROUP BY adm.id")
Page<ActivityStatistic> getActivityStatistics(LocalDateTime from,
LocalDateTime to,
long groupId,
Pageable pageable);
How can I sort it by the new field that I created: lastActionTime, approved ?
I can run it by native sql in postgresql: pgadmin. But in jpa, when I using sort with field name is approved, it auto become act.approved in JPA query.
I used to read this post Spring Data and how to sort by a column not in an Entity but it not help.
You can't apply in JPQL on a table column that isn't mapped to a property of an entity.
The reason for this is that JPA including JPQL operates on these entities.
Use a native query instead.

JPQL "DISTINCT" returns only one result

I am confused by DISTINCT in JPQL. I have two JPQL queries identical except for "DISTINCT" in one of them:
String getObjectsForFlow =
"SELECT " +
" se.componentID " +
"FROM " +
" StatisticsEvent se " +
"WHERE " +
" se.serverID IS NOT NULL " +
" AND se.flowID = :uuid " +
" AND se.componentID IS NOT NULL " +
"ORDER BY " +
" se.timeStamp desc ";
String getObjectsForFlowDistinct =
"SELECT DISTINCT " +
" se.componentID " +
"FROM " +
" StatisticsEvent se " +
"WHERE " +
" se.serverID IS NOT NULL " +
" AND se.flowID = :uuid " +
" AND se.componentID IS NOT NULL " +
"ORDER BY " +
" se.timeStamp desc ";
I run a little code to get the results from each query and dump them to stdout, and I get many rows with some duplicates for non-distinct, but for distinct I get only one row which is part of the non-distinct list.
NOT DISTINCT
::: 01e2e915-35c1-6cf0-9d0e-14109fdb7235
::: 01e2e915-35c1-6cf0-9d0e-14109fdb7235
::: 01e2e915-35d9-afe0-9d0e-14109fdb7235
::: 01e2e915-35d9-afe0-9d0e-14109fdb7235
::: 01e2e915-35bd-c370-9d0e-14109fdb7235
::: 01e2e915-35bd-c370-9d0e-14109fdb7235
::: 01e2e915-35aa-1460-9d0e-14109fdb7235
::: 01e2e915-35d1-2460-9d0e-14109fdb7235
::: 01e2e915-35e1-7810-9d0e-14109fdb7235
::: 01e2e915-35e1-7810-9d0e-14109fdb7235
::: 01e2e915-35d0-12f0-9d0e-14109fdb7235
::: 01e2e915-35b0-cb20-9d0e-14109fdb7235
::: 01e2e915-35a8-66b0-9d0e-14109fdb7235
::: 01e2e915-35a8-66b0-9d0e-14109fdb7235
::: 01e2e915-35e2-6270-9d0e-14109fdb7235
::: 01e2e915-357f-33d0-9d0e-14109fdb7235
DISTINCT
::: 01e2e915-35e2-6270-9d0e-14109fdb7235
Where are the other entries? I would expect a DISTINCT list containing eleven (I think) entries.
Double check equals() method on your StatisticsEvent entity class. Maybe those semantically different values returns same when equals() is called hence producing this behavior
The problem was the "ORDER BY se.timeStamp" clause. To fulfill the request, JPQL added the ORDER BY field to the SELECT DISTINCT clause.
This is like a border case in the interplay between JPQL and SQL. The JPQL syntax clearly applies the DISTINCT modifier only to se.componentID, but when translated into SQL the ORDER BY field gets inserted.
I am surprised that the ORDER BY field had to be selected at all. Some databases can return a data set ORDERed by a field not in the SELECTion. Oracle can do so. My underlying database is Derby -- could this be a limitation in Derby?
Oracle does not support SELECT DISTINCT with an order by unless the order by columns are in the SELECT. Not sure if any databases do. It will work in Oracle if the DISTINCT is not required (does not run because rows are unique), but if it needs to run you will get an error.
You will get, "ORA-01791: not a SELECTed expression"
If you are using EclipseLink this functionality is controlled by the DatabasPlatform method,
shouldSelectDistinctIncludeOrderBy()
You can extend your platform to return false if your database does not require this.
Still, I don't see how adding the TIMESTAMP will change the query results?
Both queries are incorrect JPQL queries, because ORDER BY clause refers to the item that is not on select list. JPA 2.0 specification contains example that matches to this case:
The following two queries are not legal because the orderby_item is
not reflected in the SELECT clause of the query.
SELECT p.product_name
FROM Order o JOIN o.lineItems l JOIN l.product p JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
ORDER BY p.price
SELECT p.product_name
FROM Order o, IN(o.lineItems) l JOIN o.customer c
WHERE c.lastname = ‘Smith’ AND c.firstname = ‘John’
ORDER BY
o.quantity
Of course it would be nicer if if implementation could give clear error message instead of trying to guess what is expected result of incorrect query.

UPDATE and JOIN with JPQL

Tutorials and samples about JPQL always deal with SELECT statement and sometimes, simple UPDATE statements. I need to update a table with a join.
I have simplified my env :
KEY
= id
- counter
APPLET
= id
! key_id (1-1)
DEVICE
= id
! applet_id (1-1)
! user_id (1-n)
USER
= id
- login
A device has a unique applet, which has a unique keyset. But an user can own several devices.
I need to reset the counter of every KEY attached to the USER login "x".
I tried some syntax with UPDATE and JOIN, without success. Any clue ?
Thank you.
What did you try and what error did you get? What is your object model?
Perhaps something like,
Update Key k set k.counter = 0 where exists (Select u from User u join u.devices d where u.login = "x" and d.applet.key = k)
See,
http://en.wikibooks.org/wiki/Java_Persistence/JPQL_BNF#Update
You could also select the objects and reset the counter in memory and commit the changes.
JPQL does not support join operations in bulk update operations.
When you edit query, nativeQuery = true, you can join.
Query should be written according to the fields in the database.
#Transactional
#Modifying
#Query(nativeQuery = true,
value = "UPDATE Team t" +
" SET current = :current " +
" FROM " +
" members," +
" account" +
" WHERE " +
" members.members_id = t.members_id " +
" AND members.account_id = :account " +
" AND t.current = :current_true ")
int updateTeam(
#Param("current") String current,
#Param("account") Long account,
#Param("current_true") Integer current_true);