2017-04-10 84 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 ...