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]
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!