2012-08-07 46 views
6

Vấn đề của tôi rất đơn giản nhưng tôi không biết cách làm cho Hibernate làm theo cách mình muốn: - bảng MainTable có nhiều-2-một với ParentTable (với 100 hàng). điểm MainTable để m = 26 hàng trong tổng số 100 hàng trong ParentTableHibernate tạo ra m + 1 truy vấn trong nhiều-một-

@ManyToOne(fetch = FetchType.EAGER) 
@JoinColumn(name = "PARENT_ID") 
@Fetch(FetchMode.JOIN) 

Khi tôi chỉ đơn giản là truy vấn "từ MainTable"

nó sẽ tạo ra 26 + 1 truy vấn

Khi tôi theo dõi các truy vấn, Truy vấn thứ nhất chỉ tải PARENT_ID được sử dụng bởi 26 truy vấn sau này. Tôi đoán nó phải có cách để tải toàn bộ PARENT_TABLE trong truy vấn 1st ..

hãy giúp đỡ bằng cách giả định rằng:

  • FetchType.EAGER là một PHẢI
  • Sử dụng từ MainTable mt trái tham gia lấy mt.parent mẹ là ok nhưng chúng tôi có nhiều hiệp hội
+0

Tránh N + 1 chọn sự cố: http://www.realsolve.co.uk/site/tech/hib-tip-pitfall.php?name=n1selects http://stackoverflow.com/questions/97197/what -is-the-n1-selects-problem –

+0

@Pangea: Cảm ơn nhưng ở đây một số nhận xét: 1) Sử dụng tìm nạp là tốt, nhưng chúng tôi có khoảng mười bảng Phụ huynh. Đó sẽ là giải pháp cuối cùng 2) Chúng tôi muốn một cái gì đó tương tự như Subselect lấy trong One-2-Many, để 1 truy vấn cho MainTable, 1 thêm cho bảng có liên quan –

+0

@Fetch (FetchMode.JOIN) và @Fetch (FetchMode.SELECT) không có sự khác biệt nào cả !!! o_0 –

Trả lời

3
// Annotate ParentTable Persistance class file with a batch Size 
@BatchSize(size=100) 
class ParentTable{ 
    .. 
} 

@ManyToOne 
@JoinColumn(name = "PARENT_ID") 

Điều này sẽ giảm số lượng truy vấn bằng n/100 + 1.

Lý do cho sự cố này là, chế độ ngủ đông sẽ tìm nạp dữ liệu ở chế độ lười bên trong, (Tôi không nói về số FetchMode.Lazy). Chế độ Lười biếng có thể được loại trừ bằng cách sử dụng FetchMode.SUBSELECT, chỉ áp dụng cho các bộ sưu tập. Khi nói đến @ManyToOne, bạn có thể chọn một dữ liệu batch, bằng cách chỉ định batchSize.

Một Mô tả ngắn về Fetch Startegies

FetchMode.SUBSELECT

Một Query cho phụ huynh, Một Query cho bảng liên quan. Chỉ áp dụng cho khung Bộ sưu tập. Chỉ có 2 truy vấn được kích hoạt.

FetchMode.SELECT

Một Query Đối với phụ huynh, N truy vấn cho trẻ em.

FetchMode.JOIN

Một Query cho phụ huynh, N truy vấn cho trẻ em, nhưng cơ sở dữ liệu phục hồi diễn ra trả trước trong JOIN.

FetchType.Batch

Một Query cho phụ huynh và n/batchSize + 1 số truy vấn bị sa thải.


Có hai loại lấy, dựa trên thời điểm truy vấn nên được thực thi.

FetchType.EAGER:

Các truy vấn được sa thải ngay lập tức.

FetchType.LAZY:

Các truy vấn được phát sinh khi đối tượng trẻ em được truy cập. Vì vậy, số lượng truy vấn được thực thi sẽ phụ thuộc vào số lượng đối tượng con được truy cập .

How the Fetch Strategies work is better explained here.

Các vấn đề liên quan