Spring JPA: @OneToOne và Lazy fetching

11/11/2022 javajpa

Bạn có bao giờ thắc mắc tại sao nullable @OnToOne bên parent (bên không lưu reference ID) lại không Lazy fetching mặc dù đã set lazy.

Ví dụ mình có 2 entity sau:

@Entity
public class User {
	@Id
	private long id;
	@Column
	private String name;
    @OneToOne(mappedBy = "user", fetch = FetchType.LAZY)
	private Passport passport;
	// Getters and Setters
}

@Entity
public class Passport {
	@Id
	private long id;
	@Column
	private String number;
	@Column
	private String address;
	@OneToOne
    @JoinColumn(name = "user_id", referencedColumnName = "id")
	private User user;
	// Getters and Setters
}

Khi findById để lấy thông tin user, mặc dù đã setting fetch = FetchType.LAZY, tuy nhiên vẫn phát sinh query thông tin Passport ngay lập tức. Lý do là vì cơ chế lazy fetch của Hibernate là khởi tạo field đó bằng một object HibernateProxy, Khi có hành động access vào object đó thì mới bắt đầu query.

Trong trường hợp trên thì Hibernate cần quyết định khởi tạo object Proxy cho field passport không hay là để giá trị null. Vì nếu user đó không có passport thì việc khởi tạo 1 object không null sẽ không hợp lý, không lẽ dev phải check tồn tại bằng getPassport().getId() ≠ null blob_sign_no.

Chính vì việc quyết định xem khởi tạo null hay object Proxy vẫn cần query trong DB nên lấy giá trị query được set luôn cho field đó.