Java 如何从Spring数据JPA返回单个结果?

Java 如何从Spring数据JPA返回单个结果?,java,jpa,spring-data,spring-data-jpa,Java,Jpa,Spring Data,Spring Data Jpa,我试图从Spring数据查询中获得一个结果。我希望从用户表返回最大的ID。我希望这会很简单,但我有点迷路了 到目前为止,基于,我得出的结论是,我需要使用规范来定义我的查询和页面d结果,指定我要检索的结果数量。不幸的是,我遇到了一个HibernateJdbcException数据访问异常 我的规范/谓词应该相当简单,并且反映了:来自用户id的订单: Page<User> result =userRepository.findAll(new Specification<User&g

我试图从Spring数据查询中获得一个结果。我希望从用户表返回最大的ID。我希望这会很简单,但我有点迷路了

到目前为止,基于,我得出的结论是,我需要使用
规范
来定义我的查询和
页面
d结果,指定我要检索的结果数量。不幸的是,我遇到了一个
HibernateJdbcException
数据访问异常

我的
规范
/
谓词
应该相当简单,并且反映了:
来自用户id的订单

Page<User> result =userRepository.findAll(new Specification<User>() {
    @Override
    public Predicate toPredicate(Root<User> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
        query.orderBy(cb.desc(root.get("id")));
        return query.getRestriction();
    }
}, new PageRequest(0, 10));

MatcherAssert.assertThat(result.isFirstPage(), is(true));
User u = result.getContent().get(0);
Hibernate错误让我有点不知所措-它要求一个
group
子句。我认为这与我创建谓词的方式有关,但我不确定如何创建这样一个简单的谓词

编辑

正如@OliverGierke所建议的,我试图从(User.class)中删除
root=query.from,但hibernate仍然抛出相同的错误(我启用了完整的hibernate查询跟踪)。然而,奇怪的是,这一次,在生成的SQL中没有
groupby
,所以我比以前更困惑了

2014-03-18 11:59:44,475 [main] DEBUG org.hibernate.SQL - 
    /* select
        count(generatedAlias0) 
    from
        User as generatedAlias0 
    order by
        generatedAlias0.id desc */ select
            count(user0_.id) as col_0_0_ 
        from
            user user0_ 
        order by
            user0_.id desc
Hibernate: 
    /* select
        count(generatedAlias0) 
    from
        User as generatedAlias0 
    order by
        generatedAlias0.id desc */ select
            count(user0_.id) as col_0_0_ 
        from
            user user0_ 
        order by
            user0_.id desc
2014-03-18 11:59:44,513 [main] WARN  hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL Error: 90016, SQLState: 90016
2014-03-18 11:59:44,513 [main] ERROR hibernate.engine.jdbc.spi.SqlExceptionHelper - Column "USER0_.ID" must be in the GROUP BY list; SQL statement:
/* select count(generatedAlias0) from User as generatedAlias0 order by generatedAlias0.id desc */ select count(user0_.id) as col_0_0_ from user user0_ order by user0_.id desc [90016-173]

您没有使用
root
进入
规范
实例来调用上的
.get(…)
方法。这使实例无法注册正在使用的
id
,因此无法透明地将其添加到结果集中

只需从(User.class)中删除
root=query.from应该可以做到这一点

但让我困惑的是,您提到您打算构建一个“按id查找”查询。您实际构建的是“按id查找所有订单”。如果它真的是您想要得到的前者,那么在
crudepository
上有一个预定义的
findOne(…)
方法可以使用

根据下面的注释,您实际想要实现的似乎是找到具有最小id的单个用户。这也可以通过简单地扩展
分页和排序存储库
来实现,然后像这样使用客户端代码:

interface UserRepository extends PagingAndSortingRepository<User, Long> { … }

Page<User> users = repository.findAll(new PageRequest(0, 1, Direction.ASC, "id"));
User user = users.getContent.get(0);
interface UserRepository扩展了分页和排序存储库{…}
页面用户=repository.findAll(新的页面请求(0,1,Direction.ASC,“id”);
User=users.getContent.get(0);

这会将结果限制在第一页,页面大小为1,按id升序排列。

我不确定为什么要获取集合以获得单个结果。如果我错了,请纠正我,但正如我解释的那样,使用
@Query
解决您的问题非常容易。将以下内容添加到存储库界面

@Query("SELECT max(t.id) FROM #{#entityName} t")
Integer getMaxId();

从谓词中删除
root=…
没有帮助。我编辑了我的问题,以反映当我从谓词中删除
root=…
时的更改。实际上,我正在尝试构建一个“查找最佳id”查询。我只对最大的
id
感兴趣。当谓词过滤了多个结果时,
crudepository
中的
findOne(…)
失败(可以理解)。老实说,我不完全确定最好的方法是什么;我是SpringData新手,仍在努力学习如何正确使用它。上面的代码示例仍然包含无效行。这是故意的吗?我会用建议的解决方法更新我的答案。谢谢;我试试你的建议。我没有在我的帖子中编辑原始代码;我现在就把它修好。有没有其他方法不起作用的原因?这是Spring数据中的一个错误吗?您只是构建了一个无效的SQL语句/条件查询…:):)知道是什么使它成为无效的条件吗?我正在尝试在不修改存储库界面的情况下执行此操作。实际上,这是一种我只在单元测试中需要的方法,因此,我尝试使用规范/谓词来检索相同的信息。你知道有什么方法可以不用修改回购接口就可以做到这一点吗?我没有使用它们的经验。从来都不需要它们。我无法向您推荐其他解决方案。对不起,和我一起工作。谢谢。这将解决您的问题,无需规格说明
@Query("SELECT max(t.id) FROM #{#entityName} t")
Integer getMaxId();