2014-09-25 96 views
1

我需要通過HQL從DB加載對象的集合,目的是使用這些對象僅用於在某些新記錄中設置關聯。延遲加載對象集合以插入HQL

請考慮以下事項:我需要發送一封電子郵件給所有學分> 50的學分,我需要保留傳輸中包含的所有收件人的跟蹤。

首先選擇學生:

Query query = sessionFactory.getCurrentSession().createQuery("from Student student left join fetch student.scores where student.credits>50"); 
List<Student> students = query.list(); 

這將返回學生的所有列的列表(非關聯屬性,如姓氏,名字,出生日期...)加載每個記錄。 問題是,當我有很多數據時,上面的查詢非常慢,並且由於大量無用的數據從數據庫傳輸到應用程序服務器而佔用大量內存。 我無法直接在實體中加載所有屬性,因爲這會殺死應用程序的其他區域。

我需要的是一種加載上述集合的方法,只用獲取的id,因爲我使用的對象只是爲關聯中的一些新對象設置它們。我知道這可以輕鬆完成OneToMany關聯,但我怎樣才能做到這一點直接查詢收集?

List<Recipient> emailRecipients = new ArrayList<>(); 
for(Student student: students){ 
    Recipient rec = new Recipient(); 

    //this is the only usage of the student object 
    rec.setStudent(student); 
    ... 
    set other properties for the recipient 
    sessionFactory.getCurrentSession().save(rec); 
} 

裏面的收件人,Student對象是設置這樣的:

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "STD_ID", nullable = false) 
private Student student; 

正如你所看到的,只需要Student對象的ID,但我不知道該怎麼辦它。

回答

1

您可以使用一種Hibernate特有技巧,即使您未提供實際的託管實體,也可以設置FK關聯。比方說,我們有一個studentId,我們可以簡單地設置:

Student student = new Student(); 
student.setId(studentId); 
rec.setStudent(student); 

這不是由標準JPA的支持,但它與Hibernate的作品。只要確保你沒有從小孩到父母的任何級聯傳播(反正你不應該這樣做)。

0

最終我只裝了studentId並修改了接收器內部的映射包括studentId還有:

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "STD_ID", insertable=false, updatable = false) 
private Student student; 

@Column(name = "STD_ID", nullable = false) 
private Long studentId; 

現在我可以簡單的設置studentId和性能要好得多。