I have next database diagram:
As you can see, tables have not foreign keys between themselves.
My entities look like this:
@Entity
@NamedEntityGraph(name = "test", attributeNodes = [
NamedAttributeNode("room"),
NamedAttributeNode("department")
])
class Employee(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null,
var firstName: String? = null,
var entryId: String? = null,
) {
@OneToOne
@JoinColumn(name = "entryId", referencedColumnName = "empId", insertable = false, updatable = false)
@Fetch(FetchMode.JOIN)
var room: Room? = null
@OneToOne
@JoinColumn(name = "entryId", referencedColumnName = "empId", insertable = false, updatable = false)
@Fetch(FetchMode.JOIN)
var department: Department? = null
}
@Entity
class Room(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null,
var number: Int? = null,
var empId: String? = null,
) : Serializable
@Entity
class Department(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Long? = null,
var name: String? = null,
var empId: String? = null,
) : Serializable
I use @NamedEntityGraph to fetch all entities in one query. And repository looks as follows:
interface EmpRepository: JpaRepository<Employee, Long> {
@EntityGraph("test")
fun getEntityById(id: Long): Employee
}
As a result, when "Deparment" and "Room" are exist in database, Hibernate generates only one request to database, which is correct:
Hibernate:
select
employee0_.id as id1_1_0_,
department1_.id as id1_0_1_,
room2_.id as id1_2_2_,
employee0_.entry_id as entry_id2_1_0_,
employee0_.first_name as first_na3_1_0_,
department1_.emp_id as emp_id2_0_1_,
department1_.name as name3_0_1_,
room2_.emp_id as emp_id2_2_2_,
room2_.number as number3_2_2_
from
employee employee0_
left outer join
department department1_
on employee0_.entry_id=department1_.emp_id
left outer join
room room2_
on employee0_.entry_id=room2_.emp_id
where
employee0_.id=?
But, when "Department" or "Room" with such emp_id is not presented in database, Hibernate generates additional request to fetch this entity again:
Hibernate:
select
employee0_.id as id1_1_0_,
department1_.id as id1_0_1_,
room2_.id as id1_2_2_,
employee0_.entry_id as entry_id2_1_0_,
employee0_.first_name as first_na3_1_0_,
department1_.emp_id as emp_id2_0_1_,
department1_.name as name3_0_1_,
room2_.emp_id as emp_id2_2_2_,
room2_.number as number3_2_2_
from
employee employee0_
left outer join
department department1_
on employee0_.entry_id=department1_.emp_id
left outer join
room room2_
on employee0_.entry_id=room2_.emp_id
where
employee0_.id=?
Hibernate:
select
department0_.id as id1_0_0_,
department0_.emp_id as emp_id2_0_0_,
department0_.name as name3_0_0_
from
department department0_
where
department0_.emp_id=?
My question is how to prevent this Hibernate behaviour, because in my real application it's a normal when inner entity is not presented in database.