2012-06-30 28 views
6

Tôi có một Hibernate cổ điển @Inheritance(strategy=InheritanceType.SINGLE_TABLE) với @DiscriminatorFormula. Nó hoạt động tốt. Tuy nhiên, có khoảng 500 giá trị khác nhau cho cơ sở dữ liệu @DiscriminatorValue và tôi cần bản đồ chỉ khoảng 30 trong số chúng cho các lớp Java (trẻ em) và phần còn lại của chúng để ánh xạ tới lớp Java cha mẹ.Lập bản đồ Đối tượng Hibernate để biết DiscriminatorValue cho InheritanceType.SINGLE_TABLE

Sự cố có thể được mô hình hóa dưới dạng ví dụ thừa kế trên Lớp động vật.

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorFormula("...") 
public class Animal implements Serializable { 
    ... 
    @Column 
    public String getName() { ... } 
} 

Vì vậy, tôi có khoảng 30 lớp con của Animal được xác định trong mã Java với @DiscriminatorValue. Khi Hibernate tìm thấy giá trị không xác định cho phân biệt đối xử, sau đó nó ném WrongClassException. Tuy nhiên, tôi cần phải ánh xạ các giá trị phân biệt đối xử không xác định này cho một thực thể, tốt nhất là lớp Thú vật. (Tôi chỉ cần sử dụng phương thức getName() trong các trường hợp như vậy.)

Tôi biết một giải pháp là đặt một CASE SQL vào @DiscriminatorFormula nhưng sau đó tôi phải nêu rõ tất cả 30 giá trị phân biệt đối xử (cộng thêm khi tôi sẽ cần phải thêm những người khác). Vì vậy, tôi đang tìm kiếm giải pháp linh hoạt hơn.

P.S. Đó là một mã di sản, vì vậy tôi không thể thay đổi mô hình.

+3

Câu hỏi rất hay! Tôi e rằng bạn đang mắc kẹt với giải pháp SQL CASE. Một cái gì đó giống như một tùy chọn 'forceDefault = true' (ánh xạ tới lớp gốc thay vì ngoại lệ) cho chú thích' @ DiscriminatorColumn' hoặc '@ DiscriminatorFormula' sẽ rất hay. Là '@ DiscriminatorValue' trên lớp gốc cũng bị thiếu trong mã làm việc của bạn hay chỉ trong ví dụ? Nếu không, có thể bạn có thể buộc ánh xạ mặc định theo cách này. Không thể thử nó ngay bây giờ nhưng tôi nghi ngờ nó, nếu '@ DiscriminatorColumn' được sử dụng một giá trị mặc định được tạo ra cho một thiếu' @ DiscriminatorValue'. – tscho

+0

'@ DiscriminatorValue' đã bị thiếu trong mã và trong ví dụ, quá. Và chi tiết nhỏ này đã thuyết phục tôi đào sâu vào mã Hibernate một lần nữa và tìm ra giải pháp. Nhìn phía dưới. – xmedeko

Trả lời

6

tscho đã chỉ cho tôi đúng hướng, vì vậy tôi đã có thể tìm ra giải pháp cho trường hợp của mình. @DiscriminatorValue đánh giá các giá trị đặc biệt @DiscriminatorValue("null")@DiscriminatorValue("not null"). Cái thứ hai là quyền cho tôi.

@Entity 
@Inheritance(strategy=InheritanceType.SINGLE_TABLE) 
@DiscriminatorFormula("...") 
@DiscriminatorValue("not null") 
public class Animal implements Serializable { 
    ... 
    @Column 
    public String getName() { ... } 
} 
+0

Rất đẹp! Bạn có thể cung cấp liên kết trong đó tài liệu này được viết hay chỉ _documented trong mã_? – tscho

+0

Tôi đã tìm thấy nó trong mã, xem lớp SingleTableEntityPersister. Bạn có thể tìm thấy một số nguồn bằng [Tìm kiếm của Google] (https://www.google.cz/search?q=hibernate%20discriminator%20value%20null). Nếu không, tôi không thể tìm thấy tài liệu chính thức. – xmedeko

2

Tin vui. Tôi vừa ghi lại hành vi này trong Hướng dẫn sử dụng mới. Đây là vấn đề JIRA.

Về cơ bản, bạn có hai lựa chọn:

  • @DiscriminatorValue("not null") như một chiến lược mùa thu lại khi không có bản đồ giá trị phân biệt rõ ràng phù hợp với các giá trị cột dữ liệu cơ bản.
  • @DiscriminatorValue("null") khi giá trị cột cơ sở dữ liệu là rỗng. Thông thường, bạn sẽ sử dụng nó cho lớp cơ sở.

Có ví dụ chi tiết về số Hibernate blog as well.

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