Reputation: 2431
I am using spring data jpa with a legacy database schema and having some problems with mapping one of the relationships. There are 2 entities in the database buyer
and employee
. One employee can have multiple buyers so its a ManyToOne
relationship from buyer to employee.
This is how I have my jpa/hibernate entities configured:
@Entity
@Table(name = "BUYER")
public class BuyerEntity {
@Id
@Column(name = "BUYER")
private Long id;
@ManyToOne
@JoinColumn(name = "EMPLOYEE_ID")
private EmployeeEntity employee;
....
and
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeEntity {
@Id
@Column(name = "EMPLOYEE_ID")
private Long id;
....
Basically, the buyer
table has the foreign key Employee_Id
pointing back to the primary key of the employee
table.
When I do a lookup for buyers, jpa/hibernate first does a query to get all buyers and then for each buyer, it runs another query to retrieve the corresponding employee information. This is extremely inefficient because we can easily retrieve the employee information along with the buyer information by adding the employee table columns in the first query.
So instead of first doing a query that looks like this:
select buyer.id from buyer join employee ...
and then for each buyer do another query:
select employee.* from employee where employee.id = ?
if we can suggest jpa/hibernate to do a single query like this:
select buyer.*, employee.* from buyer join employee ...
Any help would be appreciated.
Upvotes: 6
Views: 2512
Reputation: 21103
You should be able to issue the following query to accomplish your goal:
SELECT b FROM BuyerEntity b JOIN FETCH b.employee
You'll notice here I am applying a JOIN FETCH
which tells Hibernate not only to join the EmployeeEntity
table with the BuyerEntity
table but to also fetch the data into the relation as part of a single query to the database.
If you want to use JPA Criteria API
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<BuyerEntity> query = cb.createQuery( BuyerEntity.class );
Root<BuyerEntity> root = query.from( BuyerEntity.class );
// specify join-fetch
root.fetch( "employee", JoinType.INNER );
query.select( root );
List<BuyerEntity> results = entityManager.createQuery( query ).getResultList();
Upvotes: 1