JPA Query optimization by avoiding JOIN to lookup table? - java

Imagine a table emp:
CREATE TABLE emp
( id NUMBER
, name VARCHAR
, dept_code VARCHAR
)
and a table dept:
CREATE TABLE dept
( code VARCHAR
, name VARCHAR
)
emp.dept_code references dept.code as a ForeignKey.
These tables are mapped to JPA Entities, and the ForeignKey is modeled as an association:
#ManyToOne
#JoinColumn(name = "dept_code")
private Department department;
Given following data:
emp dept
---------------- ------------------
1 John SALS SALS Sales
2 Louis SALS SUPT Support
3 Jack SUPT
4 Lucy SUPT
I would like to write a JPA query that returns all Emloyees in the Support Department. Assume I know the PrimaryKey of the Support Department (SUPT)
I guess that would be:
SELECT emp
FROM Employee emp JOIN emp.department dept
WHERE dept.code = 'SUPT'
Question:
As the Department key SUPT code is available in the emp table, is there a way to rewrite the JPA query by avoiding the JOIN to the Department Entity?
Would this result in a performance improvement? Or is a JPA implementation (like Hibernate) smart enough to avoid the database join to the dept table?

You would usually write the query as
select emp
from employee emp
where emp.department.code = 'SUPT'
and let your provider figure out the best way to come up with the result. In the case of hibernate, yes, it is smart enough to realize it can just look at the join column.
edit : It is worth noting, that you haven't set up lazy loading in your annotations, so it's going to join the table in to create the department entity anyway :)

Related

Using #ManyToOne in where condition of JPQL JPA?

I'm working on JPA and I got stuck with syntax or right approach to write JPQL, I have entities: department and employee,
#Entity
Department
#OneToMany
Employee
-----------------------------------------
#Entity
Employee
#ManyToOne
Department
Now I have DOA where I am just adding condition dynamically to the JPQL query for where condition
I need to pull the employee who belong to XYZ department
So my JPQL looks like this
select * from employee where department='PK_OF_DEPT'
NOTE : PK_OF_DEPT is the PK (some sequence)
The error which I am getting is syntax error unknown column department, I tried giving department.id = still not working invalid path error,
NOTE : Id is the attribute name in java object
Can someone help me to get the right syntax, NOTE : I can't use FIND method since it need to be in that DOA which Is used dynamically for listing
There's not much information here, but try this
from employee left join fetch employee.department where department.id='PK_OF_DEPT'
Try this one :
#Query("select d.dname,d.deptno,e.ename,e.eno from Department d join d.employees e where d.id = ?1")
List<Object[]> getDepartmentAndEmployeeDetailsCustomQuery(int departId);

Spring framework data JPA Inner Join on multiple columns

I would like to do the following query using spring jpa. I am able to build the where clause for my statement with Predicate.toPredicate. However, I don't know how to join on more than one column. On a single column it can be done in the repository using #Query and #Param
SELECT a.name, a.column_x, b.column_y
FROM table_a a
INNER JOIN table_b b
ON b.name = a.name
AND b.pk_2 = a.pk_2
AND b.pk_3 = a.pk_3
WHERE ...;
Another question I have is, is an intermediate tableA_tableB association beneficial if I have something like this, oneToMany relations.
Table 1: thing
thing_name
type
tenant
other1
other2
Table 2: thing_sub_prop
prop_name
value
Association table: thing_thing_sub_prop
type
thing_name
tenant
prop_name
value
Or is it better to just have two tables, thing and thing_sub_prop with the primary key columns of thing repeated in thing_sub_prop as a foreign key?

Hibernate - select entity with id from another table?

I have two tables. Property name and column name in brackets.
Table Animal has fields:
animalId (animal_id), name (name), owner (owner_id)
owner is many to one relationship to owner object and owner_id column
Table Owner has fields:
ownerId (owner_id), name
I want to select an the owner of animal who has id 5. How can that be done with hibernate?
You haven't provided much, but from what you're asking for.. this should work
Query q = sess.createQuery(" select o.owner from animal as o where o.animalId = 5")

How do I insert comma separated value using Hibernate with MySQL?

How do I store integer type list in a comma-separated format in Hibernate?
For example - I have a city table where I have cityId and CityName. In another table I have employee details.An employee can be tagged with multiple city.
I have created another table for employee-city mapping where I want to store the cities in comma separated format.
Table- Employee
----------------------------
Employee_ID Employee_Name
1 Employee 1
2 Employee 2
Table -city
------------------------
City_ID City_Name
1 City_1
2 City_2
Table- Employee-City Mapping
-----------------------
Emp_ID City_id
1 1,2
2 1,2
How to do the this kind actions in Hibernate ? Please help. I am using MySQL as the database backend.
It looks like you are trying to represent a one-to-many relationship.
The conventional SQL way to represent a one-to-many relationship is via multiple rows in a join table. In your case the join table is the employee-city table with a modified design with multiple rows per city rather than multi-valued columns:
Table- Employee-City Mapping
-----------------------
Emp_ID City_id
1 1
1 2
2 1
2 2
JPA (which Hibernate supports) has direct support for mapping these relationships to Collection fields. Your Employee class would have a cities field with type List<City> annotated with #OneToMany.
#Entity
public class Employee {
#Id
#Column(name="Emp_ID")
private long id;
#OneToMany
#JoinColumn(name="Emp_ID", referencedColumnName="City_ID")
private List<City> cities;
// ... rest of the class: constructor, getters, setters
}
The following guide may also help:
https://en.wikibooks.org/wiki/Java_Persistence/OneToMany

How can I annotate this complex join in JPA?

Let's say I have the following tables:
Locations
================
LocationKey, LocationName
Employees
================
EmployeeKey, FirstName, LastName
EmployeeLocationXRef
================
EmployeeLocationXRefKey, LocationKey, EmployeeKey
TimeSheets
=================
TimeSheetKey, EmployeeLocationXRefKey, Minutes
OK, so as you can see, in order for me to get all of the TimeSheets for a Location and Employee, I can do the following in SQL
select
*
from TimeSheets ts
join EmployeeLocationXRef ex on (ex.EmployeeLocationXRefKey = ts.EmployeeLocationXRefKey)
join Locations l on (l.LocationKey = ex.LocationKey)
join Employees e on (e.EmployeeKey = ex.EmployeeKey)
where
l.LocationKey = 'xxxx'
and e.EmployeeKey = 'yyyy'
But I have tried every way I can think of to map with (with annotations) in JPA using #JoinTable, etc.
Any ideas how this could be done? Unfortunately, this is a legacy system and the schema cannot be changed.
EDIT
Forgot to mention the EmployeeLocationXRef entity has not been directly mapped. Which could be the real problem. I will see about creating that entity mapping and see if it makes it easier.
I don't see anything particularly difficult or strange about this schema. There should simply be one entity per table and (unless there are unique constraints):
a ManyToOne between EmployeeLocationXRef and Location, using a JoinColumn
a ManyToOne between EmployeeLocationXRef and Employee, using a JoinColumn
a ManyToOne between Timesheet and EmployeeLocationXRef, using a JoinColumn
(these associations can of course be made bidirectional, or be in the other direction if you prefer so).
The JPQL query would simply be
select ts from Timesheet ts
join ts.employeeXRef ex
join ex.location l
join ex.employee e
where
l.locationKey = 'xxxx'
and e.employeeKey = 'yyyy'
which is a straightforward translation of the SQL query.

Categories