2011-11-02 28 views
9

Tôi có một hệ thống phân cấp tham gia đơn giản của tài liệu:Hibernate 4: sự bền bỉ cột phân biệt InheritanceType.JOINED giá trị

CREATE TABLE Documents 
(
    id INTEGER NOT NULL, 
    discriminator ENUM('official','individual','external') NOT NULL, 
    file_name VARCHAR(200) NOT NULL, 
    PRIMARY KEY (id) 
); 

CREATE SystemDocuments 
(
    id INTEGER NOT NULL, 
    binary_data BLOB NOT NULL, 
    PRIMARY KEY (id), 
    FOREIGN KEY (id) REFERENCES Documents (id) 
); 

CREATE ExternalDocuments 
(
    id INTEGER NOT NULL, 
    PRIMARY KEY (id), 
    FOREIGN KEY (id) REFERENCES SystemDocuments (id) 
); 

Như bạn có thể xem tất cả các bảng phụ làm là chia sẻ cùng một ID từ bảng Documents. Khác hơn là SystemDocuments thêm một cột binary_dataExternalDocuments không thêm thuộc tính mới. (Cũng lưu ý có hai bảng phụ bê tông khác trong hệ thống phân cấp được biểu thị bởi 'official''individual' mà không có sự liên quan ở đây.)

Sau đây là các ánh xạ cho các bảng trên:

Document.java:

@Entity 
@Table(name = "Documents") 
@Inheritance(strategy = InheritanceType.JOINED) 
@DiscriminatorColumn(name = "discriminator", discriminatorType = DiscriminatorType.STRING) 
//@DiscriminatorOptions(force = true) // <-- Hibernate 4-specific annotation not inserting discriminator values 
public abstract class Document implements Serializable 
{ 
    @Id 
    @Column 
    protected Integer id; 

    @Column(name = "file_name") 
    protected String fileName; 

    ... 
} 

SystemDocument.java:

@Entity 
@Table(name = "SystemDocuments") 
public abstract class SystemDocument extends Document 
{ 
    @Lob 
    @Column(name = "binary_data") 
    protected byte[] binaryData; 

    ... 
} 

ExternalDocument.java:

@Entity 
@Table(name = "ExternalDocuments") 
@DiscriminatorValue(value = "external") 
public class ExternalDocument extends SystemDocument 
{ 
    ... 
} 

Lớp thứ hai là vụ phải được ánh xạ tới giá trị cột phân biệt các Documents 'external'. Khi tìm các thực thể thông qua EntityManager.find các phân biệt đối xử được trả về một cách chính xác, thực sự là vì các phân biệt đối xử của dữ liệu thử nghiệm của tôi đã được INSERTed vào DB một cách chính xác.

Bây giờ tôi sử dụng đoạn mã sau để chèn văn bản mới/file vào hệ thống thông qua JPA và một tập tin tải lên:

... 

UploadedFile uf = event.getUploadedFile(); 

// set ID, file name, and binary data 
ExternalDocument detachedExternalDocument = 
    new ExternalDocument(1234567, uf.getName(), uf.getData()); 

docService.create(detachedExternalDocument); 

Khi kiểm tra việc DB tuy nhiên tôi có thể thấy rằng Hibernate không không chèn 'external' giá trị phân biệt đối xử vào cột của bảng là discriminator.

Đã xảy ra sự cố trong quá khứ, hãy xem https://hibernate.onjira.com/browse/ANN-140 và gần đây hơn cho Hibernate 4 https://hibernate.onjira.com/browse/HHH-4358, vì vậy rất có thể đó là cách để làm việc theo cách đó.

Sau đó, tôi tìm thấy http://docs.jboss.org/hibernate/core/4.0/javadocs/org/hibernate/annotations/DiscriminatorOptions.html trong Tài liệu API Hibernate 4 hiện tại nhưng không hoạt động (xem @DiscriminatorOptions tại lớp Tài liệu).

Làm cách nào để có được Hibernate 4 để chèn các phân biệt đối xử sử dụng chú thích thô?

Lưu ý: Tôi không muốn ánh xạ cột phân biệt đối xử dưới dạng cột thông thường.

Trả lời

19

Trước hết, câu hỏi này trùng lặp với Discriminator in InheritanceType.JOINED.

Dường như các giá trị phân biệt đối xử bền bỉ trong kế thừa JOINED là không phải là theo yêu cầu của thông số JPA.Dưới đây là những gì tôi đã nhận được từ một thành viên của nhóm chuyên gia JPA qua email:

Thông số này không yêu cầu thực hiện sử dụng cột phân biệt đối xử để thực hiện thừa kế, tuy nhiên, giả sử rằng nếu @DiscriminatorColumn được chỉ định sau đó nó sẽ được sử dụng, tức là các giá trị sẽ được viết ra. Chúng tôi không nói rõ rằng nếu một @DiscriminatorColumn được chỉ định trong mã nó phải được sử dụng, giống như chúng tôi không tuyên bố rõ ràng rằng nếu một @Column hoặc @JoinColumn được chỉ định các giá trị phải được lưu trữ trong bảng, nhưng có chỉ rất nhiều mà chúng ta có thể hoặc nên chỉ định. Ở cấp độ thấp nhất, một số định luật vật lý và lý do nhất định chỉ được giả định.

Vấn đề trong tầm tay là một vấn đề với Hibernate cho khá trong một, xem tại đây:

https://hibernate.atlassian.net/browse/ANN-140

chối bình luận:

EJB3 KHÔNG yêu cầu sử dụng discriminators với JOINED chiến lược lập bản đồ. Nó được cho phép cho việc triển khai kém hơn của chiến lược lập bản đồ JOINED yêu cầu một phân biệt đối xử. Hibernate không cần một discriminator vì Hibernate là tốt hơn so với các triển khai kém khác.

Trong khi kết thúc chỉ chiến lược SINGLE_TABLE đòi hỏi một cột phân biệt, tham gia thể được thực hiện mà không có. Vấn đề với Hibernate hiện tại là nó gây ra dữ liệu không nhất quán khi lưu giữ các thực thể con trong một kế thừa JOINED ánh xạ với @DiscriminatorColumn, mặc dù đặc tả JPA khuyến nghị các giá trị phân biệt tồn tại nếu một phân biệt được sử dụng với JOINED. Xem thêm trong RFE tại đây:

https://hibernate.atlassian.net/browse/HHH-6911

+4

Có thêm nhận xét được đăng trên vé đó (HHH-6911) gần đây. Có vẻ như bây giờ Hibernate (4.2.9, 4.3.X) không còn bỏ qua cột phân biệt đối xử khi nó được khai báo rõ ràng trong mã. – Andy

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