Reference properties of null referenced object in HQL - java

Here I have two Entity class.
#Table(name = "AC_ACCOUNT_MASTER")
public abstract class Account implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "a_name")
private String name;
}
And
#Table(name = "AC_VOUCHER_MASTER")
public class Voucher implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Double amt;
#ManyToOne
private Account drAc;
#ManyToOne
private Account crAc;
}
There are 10 rows in AC_VOUCHER_MASTER table, where 4 drAc data are null in AC_VOUCHER_MASTER table.
session.createQuery("select v.id, v.amount, v.drAc.id, v.crAc.id from Voucher v").list();
The above query returns me 10 result (although 4 drAc are null). But when I put name refernce (v.drAc.name), it returns only those rows (6 rows) that drAc is not null.
"select v.id, v.amount, v.drAc.id, v.drAc.name, v.crAc.id , v.crAc.name from Voucher v"
What Should I do now ? Is there to use coalesce() or something else ?

Use a left join:
select v.id, v.amount, drAc.id, drAc.name, crAc.id , crAc.name
from Voucher v
left join v.drAc drAc
left join v.crAc crAc

Related

How to filter select from table by another table by exclusion principle

My application under Spring Boot v1.5.7
I have 3 entities (schematically):
#Entity
public class Word {
#Id
#GeneratedValue
private Integer id
...
}
#Entity
public class UserWordList {
#Id
#GeneratedValue
private Integer id
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#ManyToOne
#JoinColumn(name = "word_id")
private Word word;
}
#Entity
public class UserAnotherWordList {
#Id
#GeneratedValue
private Integer id
#ManyToOne
#JoinColumn(name = "user_id")
private User user;
#ManyToOne
#JoinColumn(name = "word_id")
private Word word;
}
And now I need to select all Words for User, but exclude Words placed in user's lists
Native SQL for user_id=1 is
select *
from Word w
left join UserWordList uwl
on w.id = uwl.word_id and uwl.user_id = 1
left join UserAnotherWordList uawl
on w.id = uawl.word_id and uawl.user_id = 1
where uwl.word_id is NULL
and uawl.word_id is NULL
What is a best way to do it? Ideally I would like to use Spring Data features or HQL, but I don't understand how...
UPD
I solve my problem with native query:
#Entity
#NamedNativeQuery(
name = "User.getWordsToProcess",
resultClass = Word.class,
query = "<...native query to select Words...>"
)
public class User {...}
...
public interface UserRepository extends CrudRepository<User, Integer> {
List<Word> getWordsToProcess(Integer userId);
}
Fastest answer is Criteria api (but that is deprecated in hibernate 5.2 and above.)
So you can use Hql :
getSession().createQuery(" select * from UserWordList u left join fetch u.word
left join fetch u.user").list()
And you can use union or create another query to fetch UserAnotherWordList.
Also you can set any restrictions in Hql like below:
Query query = getSession().createQuery(" select * from UserWordList u left join fetch u.word left join fetch u.user us where us.user = :sample").list();
query.setParameter("sample",value);
query.list();

Getting Hibernate entities from inner join on the same entity

I am trying to get the last EmergencyJob carried out by each Employee (i.e. the one with the max endTime).
I have the following entities
EmergencyJob
#Entity
#Table(name = "emergencyjobs", schema = "simulator")
public class EmergencyJob {
#Id
private String jobId;
private LocalDate dateLogged;
private LocalTime timeLogged;
private double easting;
private double northing;
private String priority;
private Point location;
#ManyToOne
private Engineer assignedEngineer;
private LocalTime startTime;
private LocalTime endTime;
...
}
Engineer
#Entity
#Table(name = "engineer", schema = "simulator")
public class Engineer {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
private int engineerId;
private Point homeLocation;
...
}
With the tables are generated by Hibernate I can do what I need in the database using the following query:
SELECT e.*
FROM simulator.emergencyjobs AS e
INNER JOIN (
SELECT
assigned_engineer_engineer_id,
max(end_time) as end_time
FROM simulator.emergencyjobs
GROUP BY assigned_engineer_engineer_id
) AS ee
ON e.assigned_engineer_engineer_id = ee.assigned_engineer_engineer_id
AND e.end_time = ee.end_time
But I can't figure out how to use this to retrieve a list of EmergencyJob entities in Hibernate.
Any help would be appreciated!
This should do the trick (fetch is optional):
select ej
from emergencyJob ej
inner join fetch ej.assignedEngineer e
where ej.endTime = (select max(distinct sej.endTime)
from emergencyJob sej
where sej.assignedEngineer = e)
Also remember to define the join column on EmergencyJob entity:
#ManyToOne
#JoinColumn(name = "assigned_engineer_engineer_id")
private Engineer assignedEngineer;

How to get child table rows using parent table ID?

I have two tables: Organization(Parent) and Department(Child).
There is One to Many relationship, and is mentioned in Organization table only.
#Entity
#Table(name="TBL_STD_ORGANIZATION")
public class Organization implements Serializable {
#Id
#GeneratedValue
#Column(name="FLD_ORG_ID")
private Long organizationId;
#Column(name="FLD_ORG_NAME")
private String orgName;
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
private java.util.List<Department> listOfDepartMents = new java.util.ArrayList<Department>();
}
Below is Department Class:
#Entity
#Table(name="TBL_STD_DEPARTMENT")
public class Department implements Serializable {
#Id
#GeneratedValue
#Column(name = "FLD_DEPARTMENT_ID")
private Long departmentId;
#Column(name = "FLD_DEPARTMENT_NAME")
private String departmentName;
}
I wrote relationship in Parent table, because of it hibernate creates third table.
Now, I have to retrieve departments start with "sa" keyword and in specific organization.
So I want the HQL or SQL query query. I am not getting it how to write such complex query.
Any suggestions?
I'm fairly certain the HQL/JPQL would be:
SELECT d FROM Organization o JOIN o.listOfDepartMents d WHERE d.departmentName LIKE "sa%"

Select only JPA Collection members meeting condition

I'm trying to select entries for Entity A where all of the children in its collection of CReference entities meet a condition. The query I currently have only requires the conditions to be met on at least one of the members.
Current Query
This query currently selects all objects of type A where at least one of the items in its c_references class
SELECT a FROM A a INNER JOIN FETCH a.c_references c_refs INNER JOIN FETCH c_refs.c_reference c_ref WHERE (c_ref.flag_one=TRUE AND c_ref.flag_two=TRUE)
Classes
Class A
#Entity
public class A{
#Id
private UUID a_uuid;
#OneToMany(fetch = FetchType.EAGER)
#JoinColumn(name = "owning_a_uuid")
private List<CReference> c_references;
}
Class CReference
#Entity
// This class keeps references to all of the A objects that have referenced a C object
public class CReference{
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long c_reference_id;
#OneToOne
private A a_referencing_c;
#OneToOne
private C c_reference;
}
Class C
#Entity
#Cacheable
public class C{
#Id
private UUID c_uuid;
private Boolean flag_one = false;
private Boolean flag_two = false;
}
Try this:
SELECT a FROM A a
WHERE NOT EXISTS(
SELECT c_refs
FROM CReference c_refs
INNER JOIN c.c_reference c_ref
WHERE
c_refs.a_referencing_c = a
AND (c_ref.flag_one = FALSE OR c_ref.flag_two = FALSE)
)

How to write query in JPQL?

I have a three classes: Doctor, Patient and Consultation.
Both Doctor and Patient classes have a list of consultations as field.
#Entity
public class Consultation {
#Id
#GeneratedValue
private int id;
private Calendar scheduleDate;
private String information;
private String symptoms;
#ManyToOne
private Doctor doctor;
#ManyToOne
private Patient patient;
//...
}
#Entity
public class Patient {
#Id
#GeneratedValue
private int id;
private String name;
private String ssn;
private String address;
#OneToMany(mappedBy = "patient")
private List<Consultation> consultations;
//...
}
#Entity
public class Doctor {
#Id
#GeneratedValue
private int id;
private String name;
private String specialization;
#OneToMany(mappedBy = "doctor")
private List<Consultation> consultations;
//...
}
I want to obtain the patients of a doctor from a single query; that is all the patients that have the same consultation as a doctor. Note that there is no connection between Doctor and Patient.
Is this posible?
select p from Patient p where p.consultations **someKeyword** (select d.consultations from Doctor d where d.id = :doctorId)
If I'm not mistaken someKeyword would be contains if there would be
where list<entity> contains entity
and in if
where entity in list<entity>
but in this case there would be
list someKeyword list
A combination would be:
select p from Patient p where p.consultations contains (select c from Consultation c where c in (select d.consultations from Doctor d where d.id = :doctorId))
but does this make sens?
I am a beginner in JPA and JPQL.
Something like:
select p from Patient p
where exists (
select c from Consultation c
where c.patient = p
and c.doctor.id = :doctorId
)
?
This tutorial might help:
JPA Tutorial
You can use the NamedQuery annotation which looks something like below
#NamedQuery(
name = "findPatientForDoctor",
query = "SELECT c.patient FROM Consultation c WHERE c.doctor.id : id"))
(just check for the syntax of this query alone)
This will give one patient for a doctor id.
Since your association is like Patient have consultations and each consutlation has one to one mapping with Patient and Doctor. Currently there is no relation in your entity model to get all the patients for a doctor. Patient to Doctor is a many to many relation and currently your entity seems not supporting that. I dont think without a patient to doctor relation you can get the records in one single query.

Categories