2016-01-28 2 views
1

Я пытаюсь запустить тестирование SQL в Apache Ignite с помощью следующего кода.Проблема с запущенными SQL-запросами сканирования в Apache Ignite в clientmode

public void testSQLDatabase(){ 
     CacheConfiguration<Long, Person> cacheCfg = new CacheConfiguration<>(); 
     cacheCfg.setName("mycache"); 
     cacheCfg.setCacheMode(CacheMode.PARTITIONED); 
     cacheCfg.setIndexedTypes(Long.class, Person.class); 

// Setting up query entity. 
     QueryEntity queryEntity = new QueryEntity(); 

     queryEntity.setKeyType(Long.class.getName()); 
     queryEntity.setValueType(Person.class.getName()); 

// Listing query fields. 
     LinkedHashMap<String, String> fields = new LinkedHashMap(); 

     fields.put("id", Long.class.getName()); 
     fields.put("orgId", Long.class.getName()); 
     fields.put("firstName", String.class.getName()); 
     fields.put("lastName", String.class.getName()); 
     fields.put("resume", String.class.getName()); 
     fields.put("salary", Double.class.getName()); 

     queryEntity.setFields(fields); 

// Listing indexes. 
     Collection<QueryIndex> indexes = new ArrayList<>(3); 

     indexes.add(new QueryIndex("id")); 
     indexes.add(new QueryIndex("orgId")); 
     indexes.add(new QueryIndex("salary")); 

     queryEntity.setIndexes(indexes); 
     cacheCfg.setQueryEntities(Arrays.asList(queryEntity)); 

     IgniteCache<Long, Person> cache = ignite.getOrCreateCache(cacheCfg); 
     cache.clear(); 

     for(long iCount = 0; iCount < 10000; iCount++) { 
      Person person = new Person(); 
      person.setValues(iCount, 0, "a", "a", "asdf", iCount*100); 
      cache.put(iCount, person); 
      System.out.println("Got back " + cache.get(iCount).toString()); 
     } 

     IgniteBiPredicate<Long, Person> filter = new IgniteBiPredicate<Long, Person>() { 
      @Override public boolean apply(Long key, Person p) { 
       return p.getSalary() > 10000d; 
      } 
     }; 

     try (QueryCursor cursor = cache.query(new ScanQuery(filter))) { 
      System.out.println(cursor.toString()); 
      for (Object p : cursor) 
       System.out.println(p.toString()); 
     } 
    } 

    public class Person implements Serializable { 
     /** 
     * Person ID (indexed). 
     */ 
     @QuerySqlField(index = true) 
     private long id; 

     /** 
     * Organization ID (indexed). 
     */ 
     @QuerySqlField(index = true) 
     private long orgId; 

     /** 
     * First name (not-indexed). 
     */ 
     @QuerySqlField 
     private String firstName; 

     /** 
     * Last name (not indexed). 
     */ 
     @QuerySqlField 
     private String lastName; 

     /** 
     * Resume text (create LUCENE-based TEXT index for this field). 
     */ 
     @QueryTextField 
     private String resume; 

     /** 
     * Salary (indexed). 
     */ 
     @QuerySqlField(index = true) 
     private double salary; 

     public void setValues(long id, long orgId, String firstName, String lastName, String resume, double salary){ 
      this.id = id; 
      this.orgId = orgId; 
      this.firstName = firstName; 
      this.lastName = lastName; 
      this.resume = resume; 
      this.salary = salary; 
     } 

     public long getId() { 
      return id; 
     } 

     public void setId(long id) { 
      this.id = id; 
     } 

     public long getOrgId() { 
      return orgId; 
     } 

     public void setOrgId(long orgId) { 
      this.orgId = orgId; 
     } 

     public String getFirstName() { 
      return firstName; 
     } 

     public void setFirstName(String firstName) { 
      this.firstName = firstName; 
     } 

     public String getLastName() { 
      return lastName; 
     } 

     public void setLastName(String lastName) { 
      this.lastName = lastName; 
     } 

     public String getResume() { 
      return resume; 
     } 

     public void setResume(String resume) { 
      this.resume = resume; 
     } 

     public double getSalary() { 
      return salary; 
     } 

     public void setSalary(double salary) { 
      this.salary = salary; 
     } 
    } 

Но я получаю исключение, брошенное в последнем, где я пытаюсь перейти курсор с после запроса сканирования.

java.lang.reflect.InvocationTargetException 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
... 
Caused by: javax.cache.CacheException: class org.apache.ignite.IgniteCheckedException: Query execution failed: GridCacheQueryBean [qry=GridCacheQueryAdapter [type=SCAN, clsName=null, clause=null, [email protected], part=null, incMeta=false, metrics=GridCacheQueryMetricsAdapter [minTime=0, maxTime=0, sumTime=0, avgTime=0.0, execs=0, completed=0, fails=0], pageSize=1024, timeout=0, keepAll=true, incBackups=false, dedup=false, prj=null, keepBinary=false, subjId=ca184604-5d57-4549-a2a2-b8601d9062ab, taskHash=0], rdc=null, trans=null] 
     at org.apache.ignite.internal.processors.cache.GridCacheUtils.convertToCacheException(GridCacheUtils.java:1618) 
     ... 6 more 
Caused by: class org.apache.ignite.IgniteCheckedException: Query execution failed: GridCacheQueryBean [qry=GridCacheQueryAdapter [type=SCAN, clsName=null, clause=null, [email protected], part=null, incMeta=false, metrics=GridCacheQueryMetricsAdapter [minTime=0, maxTime=0, sumTime=0, avgTime=0.0, execs=0, completed=0, fails=0], pageSize=1024, timeout=0, keepAll=true, incBackups=false, dedup=false, prj=null, keepBinary=false, subjId=ca184604-5d57-4549-a2a2-b8601d9062ab, taskHash=0], rdc=null, trans=null] 
     at org.apache.ignite.internal.processors.cache.query.GridCacheQueryFutureAdapter.checkError(GridCacheQueryFutureAdapter.java:267) 
     at org.apache.ignite.internal.processors.cache.query.GridCacheQueryFutureAdapter.internalIterator(GridCacheQueryFutureAdapter.java:325) 
     at org.apache.ignite.internal.processors.cache.query.GridCacheQueryFutureAdapter.next(GridCacheQueryFutureAdapter.java:171) 
     ... 11 more 
Caused by: class org.apache.ignite.IgniteCheckedException: Failed to execute query on node [query=GridCacheQueryBean [qry=GridCacheQueryAdapter [type=SCAN, clsName=null, clause=null, [email protected], part=null, incMeta=false, metrics=GridCacheQueryMetricsAdapter [minTime=0, maxTime=0, sumTime=0, avgTime=0.0, execs=0, completed=0, fails=0], pageSize=1024, timeout=0, keepAll=true, incBackups=false, dedup=false, prj=null, keepBinary=false, subjId=ca184604-5d57-4549-a2a2-b8601d9062ab, taskHash=0], rdc=null, trans=null], nodeId=06118f33-33b0-4483-bab2-fcc2306a4053] 
     at org.apache.ignite.internal.processors.cache.query.GridCacheQueryFutureAdapter.onPage(GridCacheQueryFutureAdapter.java:390) 
     at org.apache.ignite.internal.managers.communication.GridIoManager.access$1800(GridIoManager.java:103) 
     at org.apache.ignite.internal.managers.communication.GridIoManager$6.run(GridIoManager.java:972) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
     ... 1 more 
Caused by: class org.apache.ignite.IgniteCheckedException: co.near.ignite.MainExperiment$Person 
     at org.apache.ignite.internal.util.IgniteUtils.cast(IgniteUtils.java:7005) 
     at org.apache.ignite.internal.util.future.GridFutureAdapter.get0(GridFutureAdapter.java:166) 
     at org.apache.ignite.internal.util.future.GridFutureAdapter.get(GridFutureAdapter.java:115) 
     at org.apache.ignite.internal.processors.cache.query.GridCacheQueryManager$CachedResult.iterator(GridCacheQueryManager.java:2825) 
     at org.apache.ignite.internal.processors.cache.query.GridCacheQueryManager.runQuery(GridCacheQueryManager.java:1390) 
     ... 3 more 
Caused by: java.lang.ClassNotFoundException: co.near.ignite.MainExperiment$Person 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:381) 
     ... 14 more 

Поскольку я только что начал опробовать Apache Ignite, я определенно делаю что-то явно неправильное. Было бы здорово, если бы вы могли сообщить мне, как это исправить.

Также я запускаю этот код в клиентском режиме, а не как сервер. Кластер с тремя узлами работает отдельно.

ответ

2

Выполняется запрос SCAN на основе предиката. Этот запрос вызывает фильтр, который вы предоставляете на узлах сервера, так что возвращаются только те данные, которые вас интересуют. Ваша реализация ожидает, что класс Person будет там, поэтому вы получите эту ошибку. Есть два варианта, чтобы это исправить:

  • (рекомендуется) Используйте withKeepBinary() флаг и BinaryObject вместо Person объекта. См. Метод scanQuery() в [1] для примера.
  • Добавить Person класс для пути к классам всех узлов сервера.

[1] https://github.com/apache/ignite/blob/master/examples/src/main/java/org/apache/ignite/examples/datagrid/CacheQueryExample.java

+0

Спасибо за быстрый ответ, я попытался ОПЦИЯ1, как option2 не может быть сделано в моей USECASE, даже если сделано, то это будет сложно поддерживать. Теперь я получаю другую ошибку. Вызвать: java.lang.ClassCastException: java.lang.Long нельзя отнести к org.apache.ignite.binary.BinaryObject Главное отличие моего кода от этого в ссылке github - это аффинный ключ в кеше Person, но в моей. Какие-нибудь подсказки относительно того, что может быть причиной этого? – the100rabh

+1

@ the100rabh 'Long' не завернут в' BinaryObject' и передан фильтру as-is. Измените свои объявления на '' и он должен работать. –