Reputation: 2172
Hibernate newb tries to understand differences between LAZY and EAGER fetching.
Address model:
@Entity
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String street;
@Column
private String city;
@OneToOne
private Department department;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@Override
public String toString() {
return "Address [id=" + id + ", street=" + street + ", city=" + city + "]";
}
}
Department model:
@Entity
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String name;
@OneToOne(mappedBy = "department", fetch = FetchType.LAZY)
private Address address;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
@Override
public String toString() {
return "Department [id=" + id + ", name=" + name + "]";
}
}
Test method:
@Test
public void testDepartment() {
Long departmentID;
Department department;
Long addressId;
Address address;
try (Session session = SessionUtil.getSession()) {
Transaction tx = session.beginTransaction();
department = new Department();
department.setId(69L);
department.setName("company");
address = new Address();
address.setCity("city");
address.setStreet("street");
address.setDepartment(department);
session.save(department);
session.save(address);
departmentID = department.getId();
addressId = address.getId();
tx.commit();
}
try (Session session = SessionUtil.getSession()) {
department = session.load(Department.class, departmentID);
System.out.println(department.getId());
}
}
When i load the department object from db following queries are executed.
Hibernate: select department0_.id as id1_2_0_, department0_.name as name2_2_0_ from Department department0_ where department0_.id=?
Hibernate: select address0_.id as id1_0_1_, address0_.city as city2_0_1_, address0_.department_id as departme4_0_1_, address0_.street as street3_0_1_, department1_.id as id1_2_0_, department1_.name as name2_2_0_ from Address address0_ left outer join Department department1_ on address0_.department_id=department1_.id where address0_.department_id=?
1
I am quite surprised seeing the join select query as I never ask for an address object explicitly and it should be loaded lazily.
Upvotes: 2
Views: 473
Reputation: 26572
If you look at the javadoc of FetchType.LAZY you will see that there are no guaranties (as opposed to the EAGER fetchinig):
The LAZY strategy is a hint to the persistence provider runtime that data should be fetched lazily when it is first accessed. The implementation is permitted to eagerly fetch data for which the LAZY strategy hint has been specified.
This epsecially true for OneToOne optional dependencies like in your case.
Here is some further reading with some workarounds if you really need to achieve lazy loading for that relationship: post 1, post 2
Upvotes: 2