2017-07-28 11 views
1

実行時にBinaryObjectを使用してキャッシュを作成しようとしています。たとえば、Employeeなどのpojoクラスを作成し、キャッシュ値タイプとして構成する代わりに、特定のキャッシュのフィールド名とフィールドタイプを使用してキャッシュを動的に構成できる必要があります。ここで起動時にバイナリキャッシュを作成して照会します

は、いくつかのサンプルコードです:

public class EmployeeQuery { 

public static void main(String[] args) throws Exception { 
    Ignition.setClientMode(true); 
    try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { 
     if (!ExamplesUtils.hasServerNodes(ignite)) 
      return; 
     CacheConfiguration<Integer, BinaryObject> cfg = getbinaryCache("emplCache", 1); 
     ignite.destroyCache(cfg.getName()); 
     try (IgniteCache<Integer, BinaryObject> emplCache = ignite.getOrCreateCache(cfg)) { 

      SqlFieldsQuery top5Qry = new SqlFieldsQuery("select * from Employee where salary > 500 limit 5", true); 
      while (true) { 
       QueryCursor<List<?>> top5qryResult = emplCache.query(top5Qry); 

        System.out.println(">>> Employees "); 
        List<List<?>> all = top5qryResult.getAll(); 
        for (List<?> list : all) { 
         System.out.println("Top 5 query result : "+list.get(0) + " , "+ list.get(1) + " , " + list.get(2)); 
        } 
        System.out.println("..... "); 
       Thread.sleep(5000); 
      } 
     } 
     finally { 
      ignite.destroyCache(cfg.getName()); 
     } 
    } 
} 

private static QueryEntity createEmployeeQueryEntity() { 
    QueryEntity employeeEntity = new QueryEntity(); 
    employeeEntity.setTableName("Employee"); 
    employeeEntity.setValueType(BinaryObject.class.getName()); 
    employeeEntity.setKeyType(Integer.class.getName()); 
    LinkedHashMap<String, String> fields = new LinkedHashMap<>(); 

    fields.put("id", Integer.class.getName()); 
    fields.put("firstName", String.class.getName()); 
    fields.put("lastName", String.class.getName()); 
    fields.put("salary", Float.class.getName()); 
    fields.put("gender", String.class.getName()); 

    employeeEntity.setFields(fields); 
    employeeEntity.setIndexes(Arrays.asList(
     new QueryIndex("id"), 
     new QueryIndex("firstName"), 
     new QueryIndex("lastName"), 
     new QueryIndex("salary"), 
     new QueryIndex("gender") 
    )); 

    return employeeEntity; 
} 

public static CacheConfiguration<Integer, BinaryObject> getbinaryCache(String cacheName, int duration) { 
    CacheConfiguration<Integer, BinaryObject> cfg = new CacheConfiguration<>(cacheName); 
    cfg.setCacheMode(CacheMode.PARTITIONED); 
    cfg.setName(cacheName); 
    cfg.setStoreKeepBinary(true); 
    cfg.setAtomicityMode(CacheAtomicityMode.ATOMIC); 
    cfg.setIndexedTypes(Integer.class, BinaryObject.class); 
    cfg.setExpiryPolicyFactory(FactoryBuilder.factoryOf(new CreatedExpiryPolicy(new Duration(SECONDS, duration)))); 
    cfg.setQueryEntities(Arrays.asList(createEmployeeQueryEntity())); 
    return cfg; 
} 

} 

私は値としてキーと全体の従業員レコード(BinaryObject)と社員(整数)でキャッシュを設定しようとしています。上記のクラスを実行すると、次の例外が発生します。

Caused by: org.h2.jdbc.JdbcSQLException: Table "EMPLOYEE" not found; SQL statement: 
select * from "emplCache".Employee where salary > 500 limit 5 

私はここで間違っていますか?この行以外のものはありますか。

employeeEntity.setTableName("Employee"); 

次に、キャッシュにデータをストリーミングしようとしています。これは正しい方法ですか?

public class CsvStreamer { 

public static void main(String[] args) throws IOException { 
    Ignition.setClientMode(true); 

    try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) { 
     if (!ExamplesUtils.hasServerNodes(ignite)) 
      return; 
     CacheConfiguration<Integer, BinaryObject> cfg = EmployeeQuery.getbinaryCache("emplCache", 1); 
     try (IgniteDataStreamer<Integer, BinaryObject> stmr = ignite.dataStreamer(cfg.getName())) { 
      while (true) { 
       InputStream in = new FileInputStream(new File(args[0])); 
       try (LineNumberReader rdr = new LineNumberReader(new InputStreamReader(in))) { 
        int count =0; 
        for (String line = rdr.readLine(); line != null; line = rdr.readLine()) { 
         String[] words = line.split(","); 
         BinaryObject emp = getBinaryObject(words); 

         stmr.addData(new Integer(words[0]), emp); 
         System.out.println("Sent data "+count++ +" , sal : "+words[6]); 
        } 
       } 
      } 
     } 
    } 
} 

private static BinaryObject getBinaryObject(String[] rawData) { 
    BinaryObjectBuilder builder = Ignition.ignite().binary().builder("Employee"); 
    builder.setField("id", new Integer(rawData[0])); 
    builder.setField("firstName", rawData[1]); 
    builder.setField("lastName", rawData[2]); 
    builder.setField("salary", new Float(rawData[6])); 
    builder.setField("gender", rawData[4]); 
    BinaryObject binaryObj = builder.build(); 
    return binaryObj; 
} 

} 

注:これはクラスタモードで実行しています。 EmployeeQueryとCsvStreamerの両方私は1台のマシンから起動し、2台の他のマシンでサーバモードで起動しています。理想的には、アプリケーションでpojoクラスを使用しないようにし、可能な限り動的かつ汎用的なものにしたいと考えています。

答えて

2

SQLスキームを構成しなかったため、この例外が発生しています。あなたの場合(pojoオブジェクトなどを作成したくない)、2.0よりバージョンのApache Igniteに追加されたsyntacsisのようなSQLを使用することをお勧めします。次の例は設定に役立ちます。https://github.com/apache/ignite/blob/master/examples/src/main/java/org/apache/ignite/examples/datagrid/CacheQueryDdlExample.java

+0

この同じ例を実行しようとしました。最初は、PUBLICスキーマを削除できないというエラーが出ました。だから私はその句を削除しました。 次に、キャッシュのインデックスを設定する必要があるというエラーが表示されます。だから私は次の行を入れて: cacheCfg.setIndexedTypes(Long.class、QueryEntity.class); //それともObject.classですか?どちらの方法でも、org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing.queryTwoStep(IgniteH2Indexing.java:1681)のNullPointerを取得します ここでは何が欠けていますか? –

+0

ソースコードを調べました。 "if(prepared.isQuery()){" (IgniteH2Indexing.javaの1642行目)は常にfalseを返します。これは期待されていますか? このため、twoStepQryがnulであり、NPE –

+1

を取得しました。2.1リリースが27日にリリースされたことに気付きました。 ignite-2.0.0を使用していました。新しいコードベースを使用して試してみます。 –

関連する問題