2015-12-27 55 views
0

我有以下類:JPA nativeQuery返回緩存resultList

Company.class:

public class Company { 
    @JoinTable(name = "company_employee", joinColumns = @JoinColumn(name = "company_id") , inverseJoinColumns = @JoinColumn(name = "employee_id")) 
    @ManyToMany(fetch = FetchType.LAZY) 
    private Set<Employee> employees; 

    @Column(name = "score") 
    private BigDecimal score; 
} 

和Employee.class

public class Employee { 
     @ManyToMany(fetch = FetchType.EAGER, mappedBy="employees") 
     private Set<Company> companies; 
} 

公司的得分列總是空的分貝並且從未通過dao更新,因爲其他表包含每個唯一對Company-Employee的分數。 我需要Score的值,僅當我通過id獲取Employee時發生這種情況,因此這種情況下,Set中的所有Company實例都應該包含分數,因此我將獲取員工獲取Employee的Employee-Company分數對。 我有下面的代碼來實現這一目標:

public Employee get(Long id) { 
    Employee emp = (Employee) dao.find(id); 
    List<Company> compList = compnanyService.getByEmpId(id); 
    Set<Company> compSet = new HashSet<Company>(compList); 
    emp.setCompanies(compSet); 
    return emp; 
} 

及公司道contains方法:

public List<Company> getByEmpId(Long id) { 
     final Query query = this.entityManager.createNativeQuery("select company.comp_id, ...some other fields, score.score from company join score on company.company_id=score.company_id where score.employee_id=:employee_id", 
       Company.class); 
     query.setParameter("employee_id", id); 
     List<Company> comps = query.getResultList(); 
     return comps; 
} 

的問題是,getByEmpId(id)給出ResultList其中雖然在DB執行company.score爲空不爲空。

我懷疑是有一些緩存干預,所以我試圖從本地查詢中刪除一些列,並且它應該在映射時調用異常並顯示「找不到列」(或類似)消息,但此方法仍然存在給出List<Company>與他們的地方所有領域儘管Hibernate打印出我的本地查詢在控制檯與我做的所有更改。 我在這裏做錯了什麼,以及如何實現我所需要的?謝謝。

+0

如果您已經在員工和公司之間擁有雙向@ManyToMany,您爲什麼使用本機查詢從員工ID檢索相關公司?看起來您並不需要它。 – yersan

+0

因爲分數存儲在不同的表中,我需要連接才能檢索它。有沒有其他的方法? –

+0

您有一個員工實體,其中包含與該員工相關的公司實體列表:設置公司;如果您能夠通過其id找到Employee實體,那麼您已經擁有該Employee的相關公司實體。出於這個原因,我不明白爲什麼你要從公共實體獲取(Long id){..}方法的數據庫中檢索公司實體列表。 – yersan

回答

0

所以我落得這樣做是:

在DB

創建的視圖從查詢:

  1. CREATE VIEW companyscore AS select company.comp_id, score.emp_id ...some other fields, score.score from company join score on company.comp_id=score.comp_id;

  2. 創建相應的實體CompanyScore與複合主id作爲comp_id和emp_id的創造視圖爲表格。

  3. 更改員工實體:

    公共類Employee {

    @OneToMany(fetch = FetchType.EAGER) 
        @JoinColumn(name = "emp_id") 
        private Set<CompanyScore> companies; 
    

    }

這樣,我不僅有得分字段總是一致的,但我可以選擇設置顯示爲整個公司類的字段非常廣泛,我不需要這個特定情況下的所有字段。

1

它可能與第一級緩存相關聯,當使用本機SQL查詢時它可能不同步。從here

如果繞過JPA,直接在數據庫中執行DML,無論是 通過原生SQL查詢,JDBC,或JPQL UPDATE或DELETE查詢, 那麼數據庫可以是不同步的,由第1級緩存。如果您在執行DML之前已經訪問了對象 ,則它們將具有舊的 狀態並且不包含更改。取決於你在做什麼 這可能是好的,否則你可能需要從數據庫刷新受影響的對象 。

所以你可以嘗試使用refresh方法從EntityManager

+0

我認爲刷新不起作用,因爲它不會使用自定義原生查詢,公司的直接表仍然在分數中包含空值。再次:目標是用score.score替代company.score,這就是爲什麼有本地查詢 –