2009-11-30 36 views
10

Tôi có một đối tượng sản phẩm thuộc về một số danh mục nhất định, nghĩa là mối quan hệ nhiều cổ điển với một.Hibernate, chèn hoặc cập nhật mà không chọn

@Entity 
public class Product{ 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    Long id; 

    String name; 
    Double price; 
    @ManyToOne(fetch = FetchType.LAZY) 
    Category category; 
... 
} 

@Entity 
public class Category implements Identifiable { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id; 

    private String name; 
... 
} 

Tôi muốn chèn và cập nhật sản phẩm mà không cần chọn trước danh mục. Như thế này:

Product product = dao.get(productId); 
Category category = dao.get(categoryId); 
product.setCategory(category); 
dao.update(product); 

hoặc

Product product = new Product(somename); 
Category category = dao.get(categoryId); 
product.setCategory(category); 
dao.insert(product); 

Có thể cập nhật và chèn mà không loại lựa chọn? Tôi không muốn sử dụng HQL hoặc truy vấn trực tiếp cho điều đó.

Trả lời

10

session.load() tồn tại riêng cho các trường hợp như thế này. Sau đây:

Category category = session.load(categoryId); 
product.setCategory(category); 

sẽ không truy cập cơ sở dữ liệu. Nó sẽ, tuy nhiên, ném một ngoại lệ ở giai đoạn sau (trong thời gian tuôn ra, nhiều hơn hoặc ít hơn) nếu không có loại có sẵn với id nhất định.

Sử dụng load() nhanh hơn merge() và không có tác dụng phụ (cascading, vv ...)

2

Hibernate cần một cách an toàn để xác định trạng thái đối tượng của bạn. Đó là lý do tại sao nó đi một chặng đường dài để đảm bảo bạn không thể kết hợp các đối tượng từ các phiên khác nhau (vì vậy bạn không thể tải các danh mục lúc khởi động và sau đó chỉ cần sử dụng chúng sau này).

Giải pháp là để tải các loại lúc khởi động, thiết lập một nhà cung cấp bộ nhớ đệm như ehcache cho lớp này và sau đó sử dụng mã này:

Product product = new Product(somename); 
product.setCategory(session.merge(category)); 

Điều đó sẽ không gây ra bất kỳ chuyến đi vòng DB nếu bạn cấu hình bộ nhớ cache mà các thể loại thể loại không thể thay đổi.

0

Tôi vừa cố gắng sau:

Category category = new Category(categoryId); 
product.setCategory(category); 

Và nó làm việc, tôi có nghĩa kỷ lục sản phẩm trong db có liên kết chính xác đến danh mục và danh mục có id

categoryId 

chưa thay đổi.

+1

Vấn đề với cách tiếp cận này là bạn đang tạo một thể hiện mới của thực thể liên tục với cùng một số nhận dạng. Nó có thể đã làm việc cho bạn lần này bởi vì 'Danh mục' được đề cập không liên quan đến phiên ** hiện tại **; nếu có, Hibernate sẽ ném một ngoại lệ. Nó cũng nguy hiểm về tính toàn vẹn dữ liệu; nếu bạn chỉ định xếp tầng cho nhiều người trên danh mục ', mã trên sẽ ghi đè danh mục gốc của bạn với tất cả các giá trị trống (hoặc không có lỗi vi phạm ràng buộc) – ChssPly76

+0

Hm, tôi có ý nghĩa rằng tôi đang làm một cái gì đó khó chịu ở đây. Cảm ơn bạn đã làm rõ. – Vladimir

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