I run the SQL query only after the cache size has changed. The new data should be already in the cache when I run the query.
From: Cong Guo Sent: 2018年6月15日 10:01 To: [email protected] Subject: RE: SQL cannot find data of new class definition Hi, Thank you for the reply. In my original test, I do not create a table using SQL. I just create a cache. I think a table using the value class name is created implicitely. I add the new field/column using ALTER TABLE before I put new data into the cache, but I still cannot find the data of the new class in the table with the class name. It is easy to reproduce my original test. I use the Person class from ignite example. In the old code: CacheConfiguration<Long, Person> personCacheCfg = new CacheConfiguration<>(PERSON_CACHE_NAME); personCacheCfg.setCacheMode(CacheMode.REPLICATED); personCacheCfg.setQueryEntities(Arrays.asList(createPersonQueryEntity())); try(IgniteCache<Long, Person> personCache = ignite.getOrCreateCache(personCacheCfg)){ // add some data here Person p1 = new Person(…); personCache.put(1L, p1); // keep the node running and run the SQL query } private static QueryEntity createPersonQueryEntity() { QueryEntity personEntity = new QueryEntity(); personEntity.setValueType(Person.class.getName()); personEntity.setKeyType(Long.class.getName()); 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()); personEntity.setFields(fields); personEntity.setIndexes(Arrays.asList( new QueryIndex("id"), new QueryIndex("orgId") )); return personEntity; } The SQL query is: IgniteCache<BinaryObject, BinaryObject> binaryCache = personCache.withKeepBinary(); SqlFieldsQuery qry = new SqlFieldsQuery("select salary from Person"); QueryCursor<List<?>> answers = binaryCache.query(qry); List<List<?>> salaryList = answers.getAll(); for(List<?> row : salaryList) { Double salary = (Double)row.get(0); System.out.println(salary); } In the new code: I add a member to the Person class which is “private in addOn”. try(IgniteCache<Long, Person> personCache = ignite.cache(PERSON_CACHE_NAME)){ // add the new data and then check the cache size Person p2 = new Person(…); personCache.put(2L, p2); System.out.println("Size of the cache is: " + personCache.size(CachePeekMode.ALL)); } I can only get the data of the old class P1 using the SQL query, but there is no error. I use BinaryObject in the first place because the document says BinaryObject “enables you to add and remove fields from objects of the same type” https://apacheignite.readme.io/docs/binary-marshaller I can get the data of different class definitions using get(key), but I also need the SQL fields query. IgniteCache<Long, BinaryObject> binaryCache = personCache.<Long, BinaryObject>withKeepBinary(); BinaryObject bObj = binaryCache.get(1L); System.out.println(bObj.type().field("firstName").value(bObj) + " " + bObj.type().field("salary").value(bObj)); System.out.println("" + bObj.type().field("addON").value(bObj)); BinaryObject bObj2 = binaryCache.get(2L); System.out.println(bObj2.type().field("firstName").value(bObj2) + " " + bObj2.type().field("salary").value(bObj2)); System.out.println("" + bObj2.type().field("addON").value(bObj2)); Thanks, Cong From: Ilya Kasnacheev [mailto:[email protected]] Sent: 2018年6月15日 9:37 To: [email protected]<mailto:[email protected]> Subject: Re: SQL cannot find data of new class definition Hello! You can add fields to existing SQL-backed cache using ALTER TABLE ... ADD COLUMN command: https://apacheignite-sql.readme.io/docs/alter-table The recommendation for your use case, where the layout of dat1a is expected to change, is to just use SQL (DDL) defined tables and forget about BinaryObject's. With regards to your original case, i.e., a different class definition: I could spend time debugging it if you had more info, but this approach is not recommended anyway. Regards, -- Ilya Kasnacheev 2018-06-15 16:29 GMT+03:00 Cong Guo <[email protected]<mailto:[email protected]>>: Hi all, I am trying to use BinaryObject to support data of different class definitions in one cache. This is for my system upgrade. I first start a cache with data, and then launch a new node to join the cluster and put new data into the existing cache. The new data has a different class definition. I use the same class name, but add a member to the class. I can add the objects of this new class to the cache. The cache size changes and I can get both the new and old data using keys. However, when I use SQLFieldsQuery like “select id from myclassname” where id is a member exists in both the versions of classes, I can get only the old data. There is no error or exception. SQL just cannot find the data of the new class definition. How can I use SQL queries to find both the new and old data? The new data is in the cache, but it seems not being in the table using my class name. Where is the new data? Is there a new table? If yes, what is the table name? I do not expect to see the new column using the old query. I just hope to see the old fields of new data using the old queries. BTW, I use QueryEntity to set up fields and indexes in my codes. Does anyone has an example about how to add fields to existing cache dynamically? Thank you!
