2017-04-10 60 views
0

我有一個查詢標註春天JPA回購,看起來像這樣:春天JPA只返回領域,而不是實體

@Repository 
public interface MainRepository 
extends 
    JpaRepository<MainEntity, MainEntity.ID>, 
    JpaSpecificationExecutor<MainEntity> { 

    @Query("select e.start, e.finish,e.forename,e.surname from MainEntity e where e.volunteerId= :id " 
     + "and e.areaId>0 and e.isAssignment=true order by e.start") 
    List<MainEntity> findAssignments(@Param("id") int volunteerId); 
} 

這不,儘管返回類型返回MainEntity對象的列表,但是。它返回對應於請求字段類型的對象列表[]。

發生了什麼事?

+2

你試過從MainEntity e''選擇e? – 2017-04-10 19:34:24

+0

我在想這個,我試過'select * ...'和'select e。*'但都失敗了。 – NickJ

+1

'SELECT e FROM MainEntity e'將返回完整的實體。如果你想要一組字段,請檢查我的[答案](http://stackoverflow.com/a/43331990/1426227)。 –

回答

6

根據定義,JPA會從實體(或多個實體)返回Object[]列表時,該查詢返回一個投影列表,也就是一組字段。

使用Spring數據JPA可以避開Object[]並通過定義如下所示的界面中更優雅格式返回數據:

public interface MainEntityProjection { 
    String getStart(); 
    String getFinish(); 
    String getForename(); 
    String getSurname(); 
} 

並改變你的查詢方法返回上述定義的接口:

@Query("SELECT e.start, e.finish, e.forename, e.surname " + 
     "FROM MainEntity e " + 
     "WHERE e.volunteerId = :id AND e.areaId > 0 AND e.isAssignment = true " + 
     "ORDER BY e.start") 
List<MainEntityProjection> findAssignments(@Param("id") int volunteerId); 

該方法在Spring Data JPA documentation中描述。


除了春數據JPA,JPA本身SELECT NEW處理它,使用公共構造函數。你會定義一個類如下:

public class MainEntityProjection { 

    private String start; 
    private String finish; 
    private String forename; 
    private String surname; 

    public MainEntityProjection(String start, String finish, 
           String forename, String surname) { 
     this.start = start; 
     this.finish = finish; 
     this.forename = forename; 
     this.surname = surname; 
    } 

    // Getters and setters 
} 

然後你的查詢會是這樣:

SELECT NEW org.example.MainEntityProjection(e.start, e.finish, e.forename, e.surname) 
FROM MainEntity e 
WHERE e.volunteerId = :id AND e.areaId > 0 AND e.isAssignment = true 
ORDER BY e.start 

上面的查詢也有望與Spring數據JPA工作(你的方法將返回一個列表MainEntityProjection)。

檢查什麼JSR 338,定義JPA 2.1的文件說,有關使用SELECT NEW和構造函數表達式:

4.8.2構造函數表達式在SELECT子句

構造函數可以使用

SELECT列表中返回一個Java類的實例。指定的類不需要是實體或映射到數據庫。構造函數名稱必須是完全限定的。

如果在SELECT NEW子句中將實體類名稱指定爲構造函數名稱,則生成的實體實例將處於新建或分離狀態,具體取決於是否爲構造對象檢索主鍵。

如果single_valued_pa​​th_expressionidentification_variable這是一個參數構造函數引用了一個實體,通過引用的結果實體實例single_valued_pa​​th_expressionidentification_variable將在受控狀態。

例如,

SELECT NEW com.acme.example.CustomerDetails(c.id, c.status, o.count) 
FROM Customer c JOIN c.orders o 
WHERE o.count > 100 
0

這樣寫:

@Query("from MainEntity e where e.volunteerId= :id " 
     + "and e.areaId>0 and e.isAssignment=true order by e.start") 
+0

哎呀,你似乎錯過了「SELECT e」關閉JPQL –

+0

它也可以使用沒有「選擇e」 – coenni

+0

Errm,沒有它如果你符合JPA規範不能。 –

0

你不要求的實體,而是它的領域。而對象數組返回。 試試這個:。

 Select e from MainEntity e ...