2011-08-02 27 views
17

Tôi có mối quan hệ cha/con giữa hai bảng và ánh xạ tương ứng trong các lớp Java của tôi. Các bảng xấp xỉ trông như thế:chú thích để lọc kết quả của một liên kết @OneToMany

A (ref number, stuff varchar2(4000)) 
B (a_ref number, other number, foo varchar2(200)) 

và mã Java:

@Entity 
class A { 
    @Id 
    @Column(name = "REF") 
    private int ref; 

    @OneToMany 
    @JoinColumn(name = "A_REF", referencedName = "REF") 
    private Set<B> bs; 
} 

@Entity 
class B { 
    @Id 
    @Column(name = "A_REF") 
    private int aRef; 

    @Id 
    @Column(name = "OTHER") 
    private int other; 
} 

này hoạt động tốt, nhưng tôi muốn thêm một bộ lọc trên các hàng mà tôi lấy từ bảng con. Truy vấn được tạo ra trông giống như:

select a_ref, other, foo from B where a_ref = ? 

Và tôi muốn nó là:

select a_ref, other, foo from B where a_ref = ? and other = 123 

các bộ lọc bổ sung sẽ chỉ là một tên cột và một giá trị mã hóa cứng. Có cách nào để làm điều đó bằng cách sử dụng chú thích ngủ đông không?

Tôi đã xem @JoinFormula, nhưng với điều đó, tôi luôn phải tham chiếu tên cột từ bảng cha (trong thuộc tính name của JoinFormula).

Cảm ơn trước vì lời khuyên nào.

+0

Tò mò, tại sao không chỉ chuyển nó thành tham số? 'where a_ref =? và khác =? '. Giá trị được truyền vào có thể được hardcoded nếu đó là những gì bạn cần làm (tôi sẽ đề nghị sử dụng một hệ thống thuộc tính cấu hình mặc dù). – ADTC

Trả lời

26

Nó không được JPA hỗ trợ nhưng nếu bạn đang sử dụng chế độ ngủ đông như nhà cung cấp JPA thì bạn có thể sử dụng chú thích @FilterDef@Filter.

Hibernate Core Reference Documentation

Hibernate3 có khả năng xác định trước các tiêu chí lọc và đính kèm những bộ lọc ở cả hai cấp độ lớp học và mức thu. Một tiêu chí lọc cho phép bạn xác định mệnh đề giới hạn tương tự với thuộc tính hiện tại "ở đâu" có sẵn trên lớp và các thành phần bộ sưu tập khác nhau . Tuy nhiên, các điều kiện lọc này có thể được tham số . Sau đó, ứng dụng có thể quyết định thời gian chạy là một số bộ lọc nhất định phải được bật hay không và giá trị tham số của chúng là . Bộ lọc có thể được sử dụng như chế độ xem cơ sở dữ liệu, nhưng chúng được tham số bên trong ứng dụng.

dụ

@Entity 
public class A implements Serializable{ 
    @Id 
    @Column(name = "REF") 
    private int ref; 

    @OneToMany 
    @JoinColumn(name = "A_REF", referencedColumnName = "REF") 
    @Filter(name="test") 
    private Set<B> bs; 
} 

@Entity 
@FilterDef(name="test", defaultCondition="other = 123") 
public class B implements Serializable{ 
    @Id 
    @Column(name = "A_REF") 
    private int aRef; 

    @Id 
    @Column(name = "OTHER") 
    private int other; 
} 

Session session = entityManager.unwrap(Session.class); 
session.enableFilter("test"); 
A a = entityManager.find(A.class, new Integer(0)) 
a.getb().size() //Only contains b that are equals to 123 
+0

Cảm ơn, nó hoạt động tốt. Đó là một chút khó chịu mặc dù bạn phải kích hoạt nó động (tôi sẽ luôn luôn kích hoạt nó). Tôi sẽ sống với nó! – Xavier

+0

Không có phương pháp upwrap trên entityManager: ( –

+1

Xin lỗi, nó chỉ có sẵn từ JPA 2.0. Http://docs.oracle.com/javaee/6/api/javax/persistence/EntityManager.html#unwrap(java.lang. Class) –

0

với JPA 1 bạn có thể sử dụng giải pháp cung cấp nhưng thay đổi Unwrap để getDelegate là như thế

Session session = (Session)entityManager.getDelegate(); 

và nó sẽ làm việc.

0

Nếu tôi hiểu câu hỏi đúng, có một cách để làm điều này với chú thích javax.persistence (tôi đã sử dụng này trên một ManyToOne bản thân mình, và phù hợp các câu trả lời từ here):

@JoinColumns({ 
    @JoinColumn(name = "A_REF", referencedColumnName = "REF"), 
    @JoinColumn(name = "B_TABLE_NAME.OTHER", referencedColumnName = "'123'")}) 
@OneToMany 
private Set<B> bs; 

Lưu ý duy nhất báo giá trong referencedColumnName, đây là giá trị bạn đang tìm kiếm.

Thông tin thêm here.

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