0

このようなクエリがあり、期待どおりに機能しません。かなりの数のバリエーションを試しましたが、クエリで何かが欠けています。

リポジトリ コード:

@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)

何が間違っているのかわかりません。どんな助けでも大歓迎です。

4

2 に答える 2

1

よく釣れます!

一般に、配列およびコレクション ベース (アプリケーション ドメイン オブジェクト) のプロパティは null であってはならないことを付け加えておきます。空でも構いませんが、null にはなりません。これは、反復処理 (特に foreach ループが、オート ボクシング/アンボクシングの null プリミティブ型の Wrapper オブジェクトに似た、かなりあいまいな NPE につながる) と、GemFire OQL で見たように、問題になる可能性があります。

ただし、GemFire がクエリの問題の原因を特定したり、null 参照を処理できたりした場合は、より有益で役立つものであったことに同意します。

興味深いことに、この問題はおそらく 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 ステートメント (クエリ) は期待どおりに機能しました...

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");

アドレスが追加された場合にのみ「アドレス」コレクションが初期化されるように Customer を (再) コーディングし、テスト ケースでアドレスの有無にかかわらず Customers の組み合わせを使用しました。

したがって、GemFire 8.x がこれを処理しているように見えても、オブジェクトを適切に初期化するのが賢明だと思います。

于 2015-02-17T22:15:53.403 に答える
0

私たちのグループの控えめな建築家の 1 人が、この理由を見つけました。クエリが悪いのではなく、データに問題がありました。一部の顧客はメール アドレスが null で、Gemfire OQL は null コレクション要素を処理できませんでした。GemfireOQL がもっと有用なエラー メッセージを表示してくれたらもっとよかったのに。

教訓は次のとおりです。

コレクションを gemfire 7 に保存する前に、コレクションを事前に初期化します。

于 2015-02-12T23:16:39.333 に答える