You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@ignite.apache.org by DanieleBosetti <D....@cmcmarkets.com> on 2018/08/31 17:23:29 UTC

Key fields are not part of the value object

Hi,

I declared a test table with four fields, two of these are key fields.
When querying the cache using the Java api, the "value" BinaryObject does
not contain the key values, whereas using SQL all fields are shown.

That is, after running:
create table test (a int, b int, c int, d int, primary key (a,b)) with
"cache_name=test, key_type=domain.key, value_type=domain.val";
insert into test values(1,2,3,4), (3,4,5,6);
select * from test;

IgniteCache<Object, BinaryObject> cache =
ig.getOrCreateCache("test").withKeepBinary();
for (Entry<Object, BinaryObject> item : cache) {
          log.info("key={} val={}",  item.getKey(), item.getValue());
}

The output is
18:07:50.263 [main] INFO  c.t.BrowseBinaryClient - key=domain.key
[idHash=138536309, hash=783969056, A=3, B=4] val=domain.val
[idHash=665137804, hash=1464087008, C=5, D=6]
18:07:50.263 [main] INFO  c.t.BrowseBinaryClient - key=domain.key
[idHash=509559152, hash=103851104, A=1, B=2] val=domain.val
[idHash=1815370847, hash=783969056, C=3, D=4]

I understand the key values are only placed in the key object; and that not
copying the key values in the value object prevents duplication.
Anyway I need to retrieve the "full" object from the cache, that is, an
object containing all 4 fields.
(that would be similar to using "select * from table" using jdbc: all fields
are returned).


Is there a way to configure the cache, so that calling cache.get(key)
returns a BinaryObject containing all 4 fields?

Otherwise, I think the alternatives would be (I don't like them, is there
any better way do do this?)
> composing the key and the value into the final object, after retrieving it
> from the cache
> working with the "javax.entry" type
> duplicating the key fields as value fields


Thanks!



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Key fields are not part of the value object

Posted by DanieleBosetti <D....@cmcmarkets.com>.
Hi Val,
I suppose that makes sense; we'll need to either use the whole entry, or to
duplicate the fields for this specific use case.
Thank you for clarifying this point!




--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Key fields are not part of the value object

Posted by vkulichenko <va...@gmail.com>.
You're confusing object schema and SQL schema. By adding those field via
binary object builder, you amended the former, but not the latter. SQL
schema stayed the same, with (a,b) being key fields not presented in value.
I would not recommend to do this, as you can end up having weird issues (for
example, if value for field 'a' is different in key and in value).

When doing INSERTs, Ignite obviously relies on SQL schema and therefore does
not add any new fields.

Generally, I don't think your expectation to have fields duplicated is
valid. No database does that and Ignite doesn't do this either. I would
recommend to use either 'select *', or get field values from both key and
value objects.

-Val



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Key fields are not part of the value object

Posted by DanieleBosetti <D....@cmcmarkets.com>.
Hi, thanks for replying-

Actually, even though we can use the SQL facilities to inspect the caches,
the intended usage is to have Java clients, and possibly using the jcache
api to access the data; so I really need to use cache.get(key).

I looked further into this;
for this very same cache, if data is inserted using SQL and "insert into..",
then the key fields are not placed into the value object.
But if data is placed to the cache using Java api, then the key fields are
put to the value object: by continuing with the above example, I executed:

  IgniteCache<BinaryObject, BinaryObject> cache =
ig.getOrCreateCache("test").withKeepBinary();
  BinaryObjectBuilder keyBuilder = ig.binary().builder("domain.key");
  BinaryObjectBuilder valBuilder = ig.binary().builder("domain.val");
  BinaryObject key = keyBuilder.setField("A", 22).setField("B", 23).build();
  BinaryObject val = valBuilder
      .setField("A", 22).setField("B", 23).setField("C", 24).setField("D",
25) .build();
  cache.put(key, val);


Then, dumping the cache contents (or calling cache.get..) I get the
following:
Note that (22,23) is (correctly) mapped to (22,23,24,25).

19:41:16.394 [main] INFO  c.t.BrowseBinaryClient - key=domain.key
[idHash=988904418, hash=802638656, A=22, B=23] val=domain.val
[idHash=908722588, hash=-1944151425, A=22, B=23, C=24, D=25]
19:41:16.394 [main] INFO  c.t.BrowseBinaryClient - key=domain.key
[idHash=496757837, hash=783969056, A=3, B=4] val=domain.val
[idHash=1548271808, hash=1464087008, A=null, B=null, C=5, D=6]
19:41:16.394 [main] INFO  c.t.BrowseBinaryClient - key=domain.key
[idHash=17600354, hash=103851104, A=1, B=2] val=domain.val
[idHash=1733056574, hash=783969056, A=null, B=null, C=3, D=4]

So it seems the difference is due to the JDBC driver writing less fields;
and I am wondering if that is intended by design (and why?)-
I would expect for JDBC to behave differently; so that when executing
"INSERT (a,b,c,d).." it placed to the cache (a,b)->(a,b,c,d) , whereas it is
now placing (a,b)->(c,d) instead.


(the reason why we are mixing SQL and java api access is that we are
planning to have both business users (using sql) and services (java)
accessing the grid.)





--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/

Re: Key fields are not part of the value object

Posted by vkulichenko <va...@gmail.com>.
Why not use SQL API and execute a 'select *', since that's what you're
actually looking for?

-Val



--
Sent from: http://apache-ignite-users.70518.x6.nabble.com/