Gemfire クライアントでGFトランザクション中に領域内のフィールドをクエリすると、次のように表示されます。それはを実行している基準クエリインデックスのないフィールドでトランザクション中にGemfireクエリを実行する
トランザクションある下に満たしたときに私たちの試行錯誤から
は、それだけで起こる: すなわちjava.lang.ClassCastException: com.gemstone.gemfire.internal.cache.EntrySnapshot cannot be cast to com.gemstone.gemfire.internal.cache.LocalRegion$NonTXEntry at com.gemstone.gemfire.internal.cache.EntriesSet$EntriesIterator.moveNext(EntriesSet.java:183) at com.gemstone.gemfire.internal.cache.EntriesSet$EntriesIterator.<init>(EntriesSet.java:121) at com.gemstone.gemfire.internal.cache.EntriesSet.iterator(EntriesSet.java:85) at com.gemstone.gemfire.cache.query.internal.ResultsCollectionWrapper.iterator(ResultsCollectionWrapper.java:181) at com.gemstone.gemfire.cache.query.internal.QRegion.iterator(QRegion.java:225) at com.gemstone.gemfire.cache.query.internal.CompiledSelect.doNestedIterations(CompiledSelect.java:712) at com.gemstone.gemfire.cache.query.internal.CompiledSelect.doIterationEvaluate(CompiledSelect.java:577) at com.gemstone.gemfire.cache.query.internal.CompiledSelect.evaluate(CompiledSelect.java:413) at com.gemstone.gemfire.cache.query.internal.DefaultQuery.executeUsingContext(DefaultQuery.java:529) at com.gemstone.gemfire.cache.query.internal.DefaultQuery.execute(DefaultQuery.java:365)
gemfireCache.getCacheTransactionManager().begin()
と呼ばれ、その後、クエリを実行クエリ/フィールド用の機能インデックスを作成しません。 すなわち
QueryService.createIndex(String, String, String)
は、初期化時に特定のフィールドで呼び出されていない状態が領域データで nullにすることができ場あり
3:fieldName
は、いくつかの中でnullの場合 すなわち"SELECT * FROM /REGIONNAME WHERE fieldName = $1"
を実行した場合に、上記の例外がスローされます。それ以外の場合は正常です。
QueryService.newQuery("SELECT * FROM /REGIONNAME WHERE fieldName = $1")
から取得したコンパイル済みクエリを使用しています。私が間違っていなければqueryserviceはローカルのものであり、サーバー上ではクエリを実行していません。あなたはより多くの情報が必要な場合は、我々はGemFireの8.2.1以下
コメントを使用している
。
私は個人的な、JUnitのを使用してプロセスを起動します。更新2016年5月12日---
が最後に問題を説明するために一緒に簡単なテストケースを置くためにいくつかの時間を取得
---習慣。最初のテストケースは、ポート上に同じ場所にあるロケータを持つサーバを起動します。
2番目のテストケースは、クライアントプロセスを開始し、トランザクション内でインデックスなしのクエリを実行します。
public class GemfireQueryInTXTest {
@Test
public void startServer() throws Exception {
Properties props = new Properties();
System.setProperty("gemfirePropertyFile", "query_in_tx/gfserver-query-in-tx.properties");
String file = DistributedSystem.getPropertyFileURL().getFile();
props.load(new FileReader(file));
Cache cache = new CacheFactory(props).create();
RegionFactory<String, ValueEntry> factory = cache
.<String, ValueEntry>createRegionFactory("REPLICATE")
.setKeyConstraint(String.class)
.setValueConstraint(ValueEntry.class);
Region<String, ValueEntry> valueEntryRegion = factory.create("VALUEENTRY");
valueEntryRegion.put("first", new ValueEntry("firstEntry", "NotNull"));
valueEntryRegion.put("second", new ValueEntry("secondEntry", null));
CacheServer server = cache.addCacheServer();
server.setPort(40000);
server.start();
Thread.sleep(1000000L);
}
@Test
public void testRunningQueryDuringTransactionOnNullableField() throws Exception {
Properties props = new Properties();
System.setProperty("gemfirePropertyFile", "query_in_tx/gemfire-query-in-tx.properties");
String file = DistributedSystem.getPropertyFileURL().getFile();
props.load(new FileReader(file));
ClientCache cache = new ClientCacheFactory(props).create();
ClientRegionFactory<String, ValueEntry> factory = cache
.<String, ValueEntry>createClientRegionFactory("DEFAULT")
.setKeyConstraint(String.class)
.setValueConstraint(ValueEntry.class);
Region<String, ValueEntry> valueEntryRegion = factory.create("VALUEENTRY");
valueEntryRegion.registerInterest(".*", InterestResultPolicy.KEYS_VALUES);
CacheTransactionManager cacheTransactionManager = cache.getCacheTransactionManager();
QueryService localQueryService = cache.getLocalQueryService();
Query query = localQueryService.newQuery("SELECT * from /VALUEENTRY WHERE nullable = $1");
// No Exception will be thrown if create index for the field (uncomment below);
// localQueryService.createIndex("IndexName", "nullable", "/VALUEENTRY");
// ... Or run without transaction (comment below tx opening and closing)
cacheTransactionManager.begin();
System.out.println("Before Query Executed");
query.execute(new Object[]{"1"});
System.out.println("After Query Executed");
cacheTransactionManager.commit();
}
}
ドメインオブジェクト:ValueEntry.java
public class ValueEntry implements DataSerializable {
private String notNull;
private String nullable;
public ValueEntry() {
}
public ValueEntry(String notNull, String nullable) {
this.notNull = notNull;
this.nullable = nullable;
}
public String getNotNull() {
return notNull;
}
public String getNullable() {
return nullable;
}
@Override
public void toData(DataOutput dataOutput) throws IOException {
DataSerializer.writeString(notNull, dataOutput);
DataSerializer.writeString(nullable, dataOutput);
}
@Override
public void fromData(DataInput dataInput) throws IOException, ClassNotFoundException {
this.notNull = DataSerializer.readString(dataInput);
this.nullable = DataSerializer.readString(dataInput);
}
}
サーバーProertiesとxml:
cache-xml-file=query_in_tx\\cache-server.xml
start-locator=40001
locators=localhost[40001]
log-file=logs\\server.log
log-level=config
mcast-port=0
name=server
<cache>
<serialization-registration>
<instantiator id="999">
<class-name>com.testing.gemfire.domain.ValueEntry</class-name>
</instantiator>
</serialization-registration>
</cache>
クライアントProertiesとxml:
cache-xml-file=query_in_tx\\cache-query-in-tx.xml
log-disk-space-limit=100
log-file-size-limit=20
log-file=logs\\cache.log
log-level=config
mcast-port=0
name=gemfire-playground
<client-cache>
<pool name="Zero" subscription-enabled="true" read-timeout="3000"
retry-attempts="5" socket-buffer-size="65536">
<locator host="localhost" port="40001" />
</pool>
<region-attributes id="DEFAULT" refid="CACHING_PROXY" pool-name="Zero"/>
</client-cache>
PDXを試しましたか? – Swapnil
@Swapnil私たちは最初からそれを使用していなかったので、プロジェクトの規模と切り替えの努力を考えているとは思わないでください。この特定の問題については、フィールドに機能インデックスを作成して回避策を講じます。しかし、私はちょうどそれがgemfireの面白いバグかどうか疑問に思っていますか?または私は間違った方法でそれを使用させるドキュメントの特定の情報を忘れていますか? –
サンプルコードで質問を更新しました –