2014-11-03 20 views
6

Tôi đoán điều này là dễ dàng, nhưng tôi không thể tìm ra.Làm cách nào để xây dựng một phép nối nghịch cho một mối quan hệ đơn hướng?

Nếu tôi có tổ chức Foo và Bar:

@Entity 
class Foo{ 
    @OneToMany 
    List<Bar> bars; 
} 

@Entity 
class Bar{ 
    @Column 
    int data; 
} 

và nếu tôi muốn tạo ra một tham (javax.persistence.criteria.Join<Foo, Bar>) đối tượng, tôi có thể làm điều đó như thế này:

Root<Foo> root = ...; 
Join<Foo,Bar> join = root.join(Foo_.bars); 

Nhưng làm thế nào tôi có thể tạo một tham chiếu nghịch đảo

Join<Bar,Foo> inverseJoin = barRoot.join....()...? 

vì tôi không có trường java trong lớp Bar trỏ đến nó là Foo paren t, nó là quan hệ một chiều?

+0

Vâng, câu trả lời rõ ràng là: đó không phải là mối quan hệ một chiều nếu bạn cần sự tham gia nghịch đảo. Bạn đã kiểm tra bằng cách sử dụng một mối quan hệ hai chiều (thêm '@ ManyToOne' vào' Bar')? – mabi

+0

Tôi đã xem xét điều đó, nhưng tôi muốn tránh điều đó nếu có thể. –

+0

Có thể bạn cần phải sử dụng truy vấn SQL thô. Tôi không biết cách để làm những gì bạn muốn và IMHO không nên là một. – mabi

Trả lời

0

Nếu những gì bạn cần được cung cấp cho một Bar được biết đến là Foo thuộc sở hữu của nó, điều này sẽ phù hợp. Câu sẽ không được dịch sang SQL JOIN nhưng nó tương đương về mặt ngữ nghĩa.

CriteriaBuilder cb = entityManager.getCriteriaBuilder(); 
CriteriaQuery<Foo> cq = cb.createQuery(Foo.class); 

Root<Foo> fooRoot = cq.from(Foo.class); 
Root<Bar> barRoot = cq.from(Bar.class); 

cq.select(fooRoot); 
cq.where(barRoot.in(fooRoot.get("bars"))); 
+0

** barRoot.in ** I tự hỏi nếu nó hoạt động với ** bằng ** thay vì ** trong ** –

+0

** fooRoot.get ("thanh") ** là tập hợp. Sử dụng ** bằng ** sẽ cố gắng so sánh một phần tử đơn (** barRoot **) với một tập hợp, đó là sai. –

+0

Ah, cảm ơn, đã hiểu! –

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