2013-09-03 49 views
10

Tôi đang sử dụng API tiêu chí cơ bản lần đầu tiên. Đó là về trừu tượng hóa các truy vấn cho một người thợ xây chung:API tiêu chí JPA: LEFT JOIN cho các mối quan hệ tùy chọn

public TypedQuery<T> newQuery(Manager<?,T> manager) 
{ 
    CriteriaBuilder builder = this.entityManager.getCriteriaBuilder(); 

    Class<T> genericClass = (Class<T>) ((ParameterizedType) manager.getClass().getGenericSuperclass()).getActualTypeArguments()[1]; 

    CriteriaQuery<T> criteriaQuery = builder.createQuery(genericClass); 
    Root<T> root = criteriaQuery.from(genericClass); 

    ... 
} 

Cuộc gọi criteriaQuery.from(genericClass); tạo SQL INNER JOIN cho tất cả các mối quan hệ được tìm thấy trên các thực thể bằng cách mặc định. Đây là một vấn đề, bởi vì mọi mối quan hệ là null (DB NULL hoặc DB không sử dụng khóa ngoại và có tham chiếu không hợp lệ) những thực thể đó sẽ bị thiếu trong danh sách kết quả, tạo ra kết quả tìm kiếm sai.

Một ví dụ có thể được tìm thấy ở đây: JPA Criteria query Path.get left join is it possibile

Những gì tôi muốn xảy ra cho các truy vấn khởi tạo bởi lớp này/phương pháp là tất cả các mối quan hệ trên thực thể, đây genericClass, được ánh xạ như optional = true

@ManyToOne(FetchType.EAGER, optional = true) 
@JoinColumn(name = "CLOSE_USER_ID", referencedColumnName = "USER_ID") 
private User    closer; 

để tạo SQL LEFT (OUTER) JOIN thay vì INNER JOIN.

Câu hỏi:

Có tiêu chuẩn JPQ cách để thực hiện điều này? Nếu vậy, làm thế nào?

PS: thường không có cách nào để biết loại bê tông trước, vì vậy cách duy nhất tôi có thể đạt được những gì tôi cần là sử dụng metamodel của một số loại và tạo các tham gia thủ công (mà tôi muốn tránh).


Chúng tôi đang sử dụng EclipseLink 2.3

Trả lời

8

.Từ (class) không sử dụng một bên tham gia cho tất cả các mối quan hệ, nó chỉ truy vấn lớp.

Mối quan hệ sẽ chỉ được truy vấn nếu bạn sử dụng API join() hoặc fetch(), để sử dụng phép nối tham gia nối ngoài() với JoinType.LEFT.

https://en.wikibooks.org/wiki/Java_Persistence/Criteria#Join

Tôi không chắc chắn lý do tại sao bạn đang nhìn thấy tham gia nếu bạn không gọi tham gia(). Một số nhà cung cấp JPA tự động tham gia tìm nạp tất cả các mối quan hệ EAGER, đây có thể là những gì bạn đang thấy. Tôi đã luôn luôn mặc dù điều này lẻ, có lẽ nhà cung cấp JPA của bạn có một đi để được cấu hình không làm điều này, hoặc bạn có thể làm cho các mối quan hệ LAZY.

+0

IIRC vấn đề là chúng ta đang sử dụng trái tham gia cú pháp cho các mệnh đề từ, nhưng đã sử dụng các phép nối chuẩn cho các mệnh lệnh, dường như làm lu mờ các phép nối trái trước đó. – Kawu

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