2010-06-09 29 views
20

Chúng tôi có các lớp sauLàm thế nào để có được những DiscriminatorValue tại thời gian chạy

@Entity 
@Inheritance(strategy = InheritanceType.SINGLE_TABLE) // optional annotation as this is default 
@DiscriminatorColumn(name = "apType", discriminatorType = DiscriminatorType.STRING, length = 255) 
@DiscriminatorValue("AP") 
public class ApplicationProcess { 
} 

Và đây

@Entity 
@DiscriminatorValue("APS") 
public class ApplicationProcessScheme extends ApplicationProcess { 
} 

Bây giờ tôi cần phải biết khi chạy nếu ApplicationProcessDiscriminatorValueAP or APS. Vì điều này được xử lý tự động bởi jpa, tôi không có cách nào nhận được giá trị này.

Chúng tôi đang gọi một phương thức có tham số ApplicationProcess làm thông số và tôi muốn tránh sử dụng instanceof để kiểm tra loại đó là gì. Sẽ mát hơn nếu tôi có thể làm điều gì đó như

applicationProcess.getApType().equals("AP"); 

Trả lời

34

Bạn có thể lập bản đồ phân biệt bạn như là một thuộc tính chỉ đọc:

public class ApplicationProcess { 

    ... 

    @Column(name = "apType", insertable = false, updatable = false) 
    private String apType; 

} 
+0

@Shervin: Bạn có thể, nhưng nó không phải là một ý tưởng tốt, logic của bạn không nên dựa vào đó . –

+1

@Pascal: Tôi nghĩ tôi phải làm vậy. Về phía xhtml tôi không có cách nào trong biểu thức EL để nói 'instanceof' (tôi nghĩ). Vì vậy, tôi có thể cần điều này. –

+1

@Shervin: Tôi rất tiếc phải nói như vậy nhưng có vẻ như bạn có một lỗ hổng lớn trong thiết kế của bạn, ** xem ** KHÔNG BAO GIỜ phải dựa vào giá trị phân biệt đối xử (điều này đúng với mã doanh nghiệp nhưng thậm chí nhiều hơn cho xem). –

5

Chúng tôi đang kêu gọi một phương pháp mà phải mất một ApplicationProcess như tham số, và tôi muốn tránh sử dụng instanceof để kiểm tra những gì nó là loại. Sẽ mát hơn nếu tôi có thể làm điều gì đó tương tự (...)

Tôi không nghĩ rằng nó sẽ mát hơn, điều này dường như còn tồi tệ hơn gọi instanceOf với tôi: nếu vì bất cứ lý do bạn thay đổi giá trị phân biệt, nó sẽ phá vỡ mã của bạn.

Nếu bạn cần kiểm tra loại, hãy sử dụng instanceOf. Một mẹo sử dụng phân biệt đối xử sẽ không làm cho mọi thứ đẹp hơn, nó sẽ làm cho mã của bạn kém mạnh mẽ hơn.

+1

+1 Tôi hoàn toàn đồng ý. Có lẽ việc tái cấu trúc này được áp dụng: http://www.c2.com/cgi/wiki?ReplaceConditionalWithPolymorphism –

+0

Nhưng sau đó tôi sẽ phải làm một cái gì đó như thế này: pseudo code: 'if (không applicationProcess instanceof ApplicationProcessScheme)', bởi vì Tôi không thể kiểm tra đối với ApplicationProcess vì ApplicationProcessScheme cũng sẽ khớp với Vì vậy, mã sẽ là 'if (obj instanceof ApplicationProcessScheme) {// vì không có instanceof} else {// Chúng ta có một con!}' –

+1

@Shervin: Có, bạn sẽ phải làm điều đó. Tôi không nói nó lý tưởng, tôi đang nói dựa vào siêu dữ liệu sẽ tệ hơn. Trên thực tế, tôi muốn tìm gợi ý của @ Ash. –

29

tôi có thể tưởng tượng vài trường hợp nó có thể hữu ích, nhưng bất chấp những lý do tại sao bạn cần điều này, bạn có thể tạo trên lớp trừu tượng của bạn phương pháp như

@Transient 
public String getDiscriminatorValue(){ 
    DiscriminatorValue val = this.getClass().getAnnotation(DiscriminatorValue.class); 

    return val == null ? null : val.value(); 
} 
+1

Trường hợp sử dụng có thể là: một số bảng dịch rộng hệ thống với các loại (quốc gia, ngôn ngữ, giới tính, ...) và mỗi loại nhiều khóa ("pl", "uk", "us", ...) và các giá trị ("Ba Lan", "Vương quốc Anh", ...). Một số loại có thể được sử dụng trong các mối quan hệ '@ OneToMany', như quốc gia có thể được sử dụng trong một' Địa chỉ trang đích ', nhưng các loại khác chỉ có thể được sử dụng bằng cách truy vấn cơ sở dữ liệu. Vì vậy, lớp cơ sở sẽ xử lý hầu hết các loại, nhưng một vài lớp cụ thể sẽ có lớp dẫn xuất riêng của chúng. – Arjan

+0

cho tôi vấn đề với câu trả lời được chấp nhận là khi đối tượng được tạo ra và chưa được lưu, phân biệt đối xử không có mặt. Trong các trường hợp thử nghiệm nơi dữ liệu thực sự không tồn tại trong db, tôi đã có vấn đề với điều đó. Điều này làm việc tuyệt vời. Cảm ơn –

+0

Điều này đang hoạt động rất tốt. –

0

Bạn có thể sử dụng chú thích công thức. Nếu bạn đang sử dụng Hibernate, bạn có thể sử dụng mã dưới đây theo this link:

private String theApType; 

@Formula("apType") 
String getTheApType() { 
    return theApType; 
} 

Tất nhiên bạn sẽ có thể sử dụng nó trong các truy vấn của bạn.

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