首先,在我们开始之前有一个家务...
我看到您在上面的 GemFire 文档参考中引用了Pivotal GemFire ,但随后参考了 Spring Data GemFire (SDG)参考文档。我当然希望您不要尝试将 SDG与 Pivotal GemFire一起使用。SDG 1.3.3 已经过时,基于 Pivotal GemFire 7.0.1,不再受支持。9.71.3.3.RELEASE1.3.3.RELEASE9.7
我怀疑您没有使用 SDG 1.3.x,因此您可能应该始终参考最新的文档,可在此处获得,特别是在此处。即使是Google 搜索也会显示最新的文档。
此外,您可以参考Spring Data for Pivotal GemFire 版本兼容性矩阵了解更多详细信息。反正...
所以,我写了一个测试类来更好地理解你的 UC。
在我的测试中,我用一个可查询的field/property建模了一个Person 类。我有一个PersonRepository类型,我写了一个与你上面的例子非常相似的查询,按年龄查询一个人,以通常以及空安全的方式。agePerson
问题是,您希望通过返回来防止结果缺失的愿望,null或者在Repositories0的情况下是模棱两可的。
对于 1,如果您返回了多个结果(例如,如SELECT a.num FROM /SomeRegion a; 即没有谓词),并且结果没有排序,那么您将无法知道哪个值是null哪个键,除非您还返回结果中的键放。
当然,这里不是这种情况,您确实使用谓词(即... WHERE a.id = $1)通过 ID 限定了查询。但是,在这种情况下,在查看查询(即SELECT a.num FROM ...)时,并不清楚给定 ID(即 Key)是否没有结果,或者只是num是null。你真的不知道。
我的测试继续说明这一点。
我有2个人["Jon Doe", "Jane Doe"],在这里。乔恩有一个公布的年龄,而简没有。当然,这两个人都存在于缓存中(即“人”区域)。
当我查询 Jon 并断言他的年龄时,我得到了预期的结果。
或者,当我查询 Jane 并断言她的年龄时,我可以得到两个值中的一个,或者null或0,正如这里所期望的那样(目前0因为我正在使用null-safe query)。如果我将查询更改为通常的查询,那么 Jane's 的返回值age实际上是null,我可以这样断言。
然而,当我们开始查询一个不存在的人时,GemFire 的行为是明确的;没有结果。我说明了这两种不同的方式(除了使用存储库),直接使用 GemFire 的QueryServiceAPI,然后再次使用 SDG 的便捷GemfireTemplate类,它简单地包装了 GemFire 查询 API(这也是存储库在后台使用的方法;真的,存储库添加的值是映射/转换功能)。
如您所见,我必须处理没有结果的情况,例如.
在存储库的情况下,因为您使用了自定义查询,所以存储库基础结构并不能立即看出哪一部分(即查询的中间结果)是null.
如果你有SELECT person.address.city.name FROM ...呢?
是人null、地址null还是城市null?这应该如何始终如一地处理?人可能会离开,但地址可能会离开null,这可能会导致与人或城市都存在不同的行为null。
事实上,Repository抽象确实处理了null返回值,正如可以在此处看到的那样。
那么,我们该何去何从?
我们有几种选择:
你可以执行和存在检查,首先......
返回 personRepository.existsById(bobDoe.getName()) ?personRepository.getAge(bobDoe.getName()) : 0;
您可以在 DAO 中的存储库之外处理此问题(也许调整/装饰存储库并委托简单的查询案例,而不是涉及使用@Query注释的复杂查询,应该谨慎使用)。
@Repository 类 PersonDao {
@Autowired
private PersonRepository personRepository;
Person findById(String name) {
return this.personRepository.findById(name).orElse(null);
}
Integer getAge(String name) {
// Either use the approach in #1, or do https://github.com/jxblum/contacts-application/blob/master/tests-example/src/test/java/example/tests/spring/data/gemfire/NullValueReturningRepositoryQueryMethodIntegrationTests.java#L143-L151.
}
...
}
仍然
另一种选择是让我们在 SD 中提供额外的支持,类似于...
@Nullable Integer getAge(String name);
也许...
Optional<Integer> getAge(String name);
这种方法仍然不能解决歧义问题,需要更多的思考。
如果 OQL 处理 Elvis 运算符,那将是非常好的,例如(在我上面更复杂的示例中)......
SELECT person?.address?.city?.name FROM /People ...
无论如何,我希望这能给你一些想法。在继续前进之前,我需要更多地考虑上面的#3。
如果您有其他问题/反馈/想法,请在评论中提供或随时提交JIRA 票证。
谢谢!