2011-01-03 7 views
11

Tôi đang sử dụng chế độ ngủ đông + chơi! khuôn khổ tại nơi làm việc, có một "thực hành tốt nhất" trên chèn một số lượng tốt các hồ sơ bằng cách sử dụng ngủ đông? Đó là khoảng 6.000 đến 10.000 cho mỗi tập tin văn bản vì vậy tôi không biết nếu Hibernate sẽ bị nghẹt thở trong công việc hoặc ném một ngoại lệ.Cách tốt nhất để chèn một số lượng tốt các bản ghi trong hibernate

Bất kỳ đề xuất nào cho tôi biết, hãy cho tôi biết nếu tôi phải giải thích thêm

Trả lời

23

Từ * Java Persistence và Hibernate"(Manning) và sau một bình luận từ Pangaea, sử dụng một stateless session (mà không có một bộ nhớ cache bối cảnh bền bỉ):

StatelessSession session = sessionFactory.openStatelessSession(); 
Transaction tx = session.beginTransaction(); 
for (int i=0; i<100000; i++) { 
    Item item = new Item(...); 
    session.insert(item); 
} 
tx.commit(); 
session.close(); 
+4

Tôi sẽ không sử dụng Phiên cho các hoạt động hàng loạt. StatelessSesssion có nghĩa là để làm các hoạt động số lượng lớn như thế này vì nó không duy trì bộ nhớ cache cấp 1: Thay đổi "sessionFactory.openSession()" thành "sessionFactory.openStatelessSession()". Đọc phần "13.3" tại đây http://docs.jboss.org/hibernate/core/3.3/reference/en/html/batch.html –

+0

Cảm ơn bạn Pangea, tôi không biết điều này. – Kartoch

+0

Tôi không chắc chắn session.clear() cần phải được giữ trong ví dụ này: không cần phải gỡ bỏ tất cả các đối tượng từ bộ nhớ cache phiên vì không có bộ nhớ cache với phiên không quốc tịch. Tôi sẽ viết điều này trong nguồn ... – Kartoch

1

Chỉ cần mở phiên và giao dịch của bạn.

Thêm tất cả các phần tử vào lưu phiên.

Sau đó, cam kết giao dịch.

//Remember to effective handler errors 
public void saveAll(List<Object> list) throws Exception{ 
Session s = HibernateUtil.openSession(); 
Transaction tx = s.beginTransaction(); 
for(Object obj : list) 
s.save(obj); 
tx.commit(); 
s.flush(); 
s.close(); 
} 
+3

Vui lòng không làm điều này. Đối với các giao dịch theo lô, tốt nhất là tránh bộ nhớ đệm phiên, nếu không, bạn sẽ phải đối mặt với ngoại lệ OOM. Đối với kịch bản cụ thể này tồn tại StatelessSession, như đã đề cập bởi Pangea trong câu trả lời của Kartoch. – jpkrohling

-5

Bạn có thể luôn có được một đối tượng kết nối trực tiếp trong trường hợp bạn muốn làm chèn ngoài hibernate.

Connection connection = DB.getConnection(); 
+1

Bạn có thể giải thích cách giải quyết vấn đề này không? – Phani

1

tốt nhất là sử dụng StatelessSessions. Hãy xem xét ví dụ sau từ (http://docs.jboss.org/hibernate/orm/3.3/reference/en-US/html/batch.html):

StatelessSession session = sessionFactory.openStatelessSession(); 
Transaction tx = session.beginTransaction(); 

ScrollableResults customers = session.getNamedQuery("GetCustomers") 
    .scroll(ScrollMode.FORWARD_ONLY); 
while (customers.next()) { 
    Customer customer = (Customer) customers.get(0); 
    customer.updateStuff(...); 
    session.update(customer); 
} 

tx.commit(); 
session.close(); 
2

Chỉ cần sửa một số mã trong câu trả lời của Kartoch.

Theo Batch Procession, "Các hoạt động chèn(), cập nhật() và xóa() do giao diện StatelessSession xác định được coi là các hoạt động cấp hàng cơ sở dữ liệu trực tiếp. Kết quả là thực thi ngay lập tức SQL INSERT, UPDATE hoặc DELETE tương ứng, chúng có các ngữ nghĩa khác nhau cho các hoạt động save(), saveOrUpdate() và delete() được định nghĩa bởi giao diện Session. "

Không còn lưu(), flush(), clear() cho StatelessSession. Mã nên được như thế này:

StatelessSession session = sessionFactory.openStatelessSession(); 
Transaction tx = session.beginTransaction(); 

for (int i=0; i<100000; i++) { 
    Item item = new Item(.....); 
    session.insert(item); 
}  

tx.commit(); 
session.close(); 

Cuối cùng, đây là một cuộc thảo luận về sự khác biệt giữa chèn hàng loạt bình thường và chèn StatelessSession: Using StatelessSession for Batch processing.