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]<mailto:[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!

Reply via email to