2017-06-14 53 views
1

我正在用JPA和Postgres db編寫服務。我有一類名爲學生:沒有加入子表的JPA(@OneToMany)查詢

public class Student { 
    @id 
    private String id; 

    private String firstName; 
    private String lastName; 

    @OneToMany(targetEntity = Phone.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 
    @JoinColumn(name = "student_id", referencedColumnName = "id") 
    private Set<Phone> phones; 

    // Setter and Getter 
} 

和電話類:

public class Phone { 
    @id 
    private String id; 

    private String number; 

    // Setter and Getter 
} 

現在會出現在我的數據庫中的兩個表,下面是他們列:

學生:身份證,名字,姓氏

電話:ID,數量,student_id數據(由@JoinColumn生成)

現在,每當我查詢學生時,JPA都會將電話表加入學生表,學生結果包含此學生的電話信息。這正是我想要的。

但現在我遇到了一個問題。當我查詢學生列表時,電話信息在這種情況下無用,只有id,firstName和lastName是必需的。但JPA也爲我做了同樣的「加入」操作。我知道這消耗了很多時間。在這種情況下,我怎樣才能返回學生表中的信息?沒有加入電話表?

我試圖在庫類似

@Query(SELECT s.id, s.firstName, s.lastName FROM student s) 
public List<Student> findAllStudentWithoutPhone(); 

但它返回我的值的列表,但不能轉換成Student對象。我怎麼能實現這個功能?

回答

2

在一個一對多映射(參閱下文)已設置的提取類型是懶惰取= FetchType.LAZY因此冬眠不會取指令設置對應於學生手機,直到訪問組的手機通過getter方法,所以不用擔心。

@OneToMany(targetEntity = Phone.class, fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) 
@JoinColumn(name = "student_id", referencedColumnName = "id") 
private Set<Phone>; 

但是如果你需要覈實情況是否工作正常與否,你可以設置該屬性show_sql爲真,並檢查通過休眠生成的SQL。

2

fetch = FetchType.LAZY爲您提供了可能性,直到第一次調用代碼時纔會查詢Phone表。請參閱:http://docs.oracle.com/javaee/7/api/javax/persistence/FetchType.html#LAZY

在情況下,如果你要檢索的學生名單沒有電話查詢應該是: @Query(SELECT * FROM student s where phones IS NULL)

自動轉換成果轉化爲學生的對象,請不要在查詢中使用s.id, s.firstName, s.lastName

1

@Sahil給出的答案絕對正確,但補充說明。

@Cong 您不需要添加FetchType.LAZY,因爲默認情況下它已經是LAZY了。 &作爲一個筆記Student手機類屬性缺少變量名稱。

+0

謝謝@mAc,變量被添加。 –