使用JPA查询时getFirstResult()返回0的问题求助
问题分析与解决方案
嗨,我一眼就看出问题所在啦——你完全用错了getFirstResult()这个方法!
核心错误:对getFirstResult()的误解
getFirstResult()根本不是用来判断查询是否有结果的,它是JPA里分页查询时用来指定结果集起始位置的方法,默认值就是0(表示从第一条结果开始取)。不管你的查询有没有匹配到数据,它的返回值都是0,除非你手动调用setFirstResult(int)设置过其他值。所以你用它来判断用户是否存在,完全是南辕北辙。
正确的判断方式
有两种常用的方法可以正确判断查询是否存在数据:
方法1:使用getResultList()判断结果是否为空
修改你的read方法,先获取结果列表,再判断列表是否非空:
@Override public String read(long id) { TypedQuery<Person> createNamedQuery = em.createNamedQuery("findQuery", Person.class); createNamedQuery.setParameter("id", id); // 获取结果列表 List<Person> resultList = createNamedQuery.getResultList(); if (!resultList.isEmpty()) { Person singleResult = resultList.get(0); creationMessage = "User: " + singleResult.getName() + " exists in database"; } else { creationMessage = "User was not found in database"; } return creationMessage; }
方法2:捕获NoResultException(适合确定最多一条结果的场景)
因为你的查询是根据主键id查找,理论上最多只会有一条结果,所以可以用getSingleResult(),但要注意这个方法在没有匹配结果时会抛出NoResultException,需要捕获:
@Override public String read(long id) { TypedQuery<Person> createNamedQuery = em.createNamedQuery("findQuery", Person.class); createNamedQuery.setParameter("id", id); try { Person singleResult = createNamedQuery.getSingleResult(); creationMessage = "User: " + singleResult.getName() + " exists in database"; } catch (NoResultException e) { creationMessage = "User was not found in database"; } return creationMessage; }
额外需要注意的点
- 实体类的Getter方法:你的
Person类里只定义了字段,没有对应的getName()等getter方法,这样在获取singleResult.getName()时会编译报错,记得补上所有字段的getter(和setter,如果你需要修改字段的话)。 - JTA事务问题:如果你的
Person对象是刚添加的,要确保添加操作已经在事务中提交,否则在同一个事务外的查询可能看不到新添加的数据。JTA下通常需要用@Transactional注解或者手动管理事务提交。
内容的提问来源于stack exchange,提问作者ravencrest
相关产品推荐
相关产品推荐

