我有查询,看起来像这样,并没有按预期工作。我尝试了很多不同的变体,但我遗漏了一些查询。
存储库代码:
@Query("SELECT c FROM /customer c, c.emailAddresses email WHERE email.emailAddress = $1")
List<CustomerEntity> findByEmailAddress(String emailAddress);
模型:
public class CustomerEntity {
@Id
protected String id;
private List<CustomerEmailAddressEntity> emailAddresses;
}
public class CustomerEmailAddressEntity {
private Long id;
private String emailAddress;
}
我得到的堆栈看起来像这样:
Caused by: java.lang.ClassCastException: com.gemstone.gemfire.cache.query.internal.Undefined cannot be cast to com.gemstone.gemfire.cache.query.SelectResults
at com.gemstone.gemfire.internal.cache.PRQueryProcessor.executeSequentially(PRQueryProcessor.java:330)
at com.gemstone.gemfire.internal.cache.PRQueryProcessor.executeQuery(PRQueryProcessor.java:127)
at com.gemstone.gemfire.internal.cache.PartitionedRegionQueryEvaluator.executeQueryOnLocalNode(PartitionedRegionQueryEvaluator.java:1370)
at com.gemstone.gemfire.internal.cache.PartitionedRegionQueryEvaluator.executeQueryOnRemoteAndLocalNodes(PartitionedRegionQueryEvaluator.java:339)
at com.gemstone.gemfire.internal.cache.PartitionedRegionQueryEvaluator.queryBuckets(PartitionedRegionQueryEvaluator.java:442)
at com.gemstone.gemfire.internal.cache.PartitionedRegion.doExecuteQuery(PartitionedRegion.java:1909)
at com.gemstone.gemfire.internal.cache.PartitionedRegion.executeQuery(PartitionedRegion.java:1829)
at com.gemstone.gemfire.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:234)
at com.gemstone.gemfire.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:195)
at com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand.processQueryUsingParams(BaseCommand.java:1402)
at com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand.processQuery(BaseCommand.java:1347)
at com.gemstone.gemfire.internal.cache.tier.sockets.command.Query.cmdExecute(Query.java:88)
at com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand.execute(BaseCommand.java:174)
at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.doNormalMsg(ServerConnection.java:809)
at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.doOneMessage(ServerConnection.java:940)
at com.gemstone.gemfire.internal.cache.tier.sockets.ServerConnection.run(ServerConnection.java:1189)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at com.gemstone.gemfire.internal.cache.tier.sockets.AcceptorImpl$1$1.run(AcceptorImpl.java:532)
at java.lang.Thread.run(Thread.java:724)
我不确定我做错了什么。任何帮助表示赞赏。
答案 0 :(得分:1)
好抓!
我想补充一点,通常,基于数组和基于集合的(应用程序域对象)属性永远不应为null。清空,但永远不会为空。这对于迭代来说可能是有问题的(特别是使用foreach循环导致相当模糊的NPE,类似于自动装箱/拆箱中的空原始类型Wrapper对象)并且如您所见,GemFire OQL。
尽管如此,如果GemFire发现查询问题的原因或者能够处理空引用,我会同意它会提供更多信息和帮助。
有趣的是,这个问题可能与GemFire 7.0.2有关。我刚刚使用GemFire 7.0.2和(最新的)GemFire 8.1.0测试了这个场景。
使用7.0.2时,发生以下异常......
org.springframework.dao.InvalidDataAccessApiUsageException: Result object returned from GemfireCallback isn't a SelectResult: [UNDEFINED]
...
但是,使用GemFire 8.1.0,OQL语句(Query)按预期工作,即使嵌套的Collection在我的应用程序域对象上未初始化...
class Customer ... {
Set<Address> addresses;
...
}
interface CustomerRepository implements GemfireRepository<Customer, Long> {
@Query("<trace> SELECT DISTINCT c FROM /Customers c, c.addresses a WHERE a.city = $1")
List<User> findCustomersInCity(String city);
}
则...
customerRepo.findCustomersInCity("Portland");
我(重新)对我的客户进行了编码,以便只有在添加地址时才会初始化'地址'集合,并且在我的测试用例中我使用了包含和不包含地址的客户组合。
所以,即使GemFire 8.x似乎可以解决这个问题,我仍然认为正确初始化一个对象是明智的。
答案 1 :(得分:0)
我们小组中一位谦虚的建筑师找到了原因。这不是一个糟糕的查询,但数据存在问题。一些客户有空电子邮件地址,Gemfire OQL无法处理null集合元素。如果GemfireOQL给我一个更有用的错误信息会更好。
经验教训:
在将您的收藏存储到gemfire 7之前预先初始化您的收藏。