Hello,

>  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”
Yes, you can dynamically add fields to BinaryObject using
BinaryObjecyBuilder, but fields that you want to query have to be specified
on node startup for example through QueryEntity.
Please take a look at this page:
https://apacheignite.readme.io/v2.5/docs/indexes#queryentity-based-configuration

I would suggest specifying a new field via QueryEntity in XML configuration
file and restart your cluster. I hope it helps.

Thanks!

пн, 18 июн. 2018 г. в 16:47, Cong Guo <[email protected]>:

> Hi,
>
>
>
> Does anyone have experience using both Cache and SQL interfaces at the
> same time? How do you solve the possible upgrade? Is my problem a bug for
> BinaryObject? Should I debug the ignite source code?
>
>
>
> *From:* Cong Guo
> *Sent:* 2018年6月15日 10:12
> *To:* '[email protected]' <[email protected]>
> *Subject:* RE: SQL cannot find data of new class definition
>
>
>
> 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]
> <[email protected]>]
> *Sent:* 2018年6月15日 9:37
> *To:* [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]>:
>
> 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!
>
>
>

Reply via email to