You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Taras Ledkov (JIRA)" <ji...@apache.org> on 2018/01/16 09:35:00 UTC
[jira] [Commented] (IGNITE-7411) JDBC thin client selects NULL
cache ID values of entries added with Java API
[ https://issues.apache.org/jira/browse/IGNITE-7411?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16326929#comment-16326929 ]
Taras Ledkov commented on IGNITE-7411:
--------------------------------------
Looks like an invalid usage and not a bug.
1. {{CREATE TABLE PERSON (ssn BINARY(16), orgId BINARY(16), name BINARY(16), PRIMARY KEY(ssn, orgId))}}
Creates the cache with key that is binary object with type {{SQL_PUBLIC_PERSON_<UUID>_KEY}}. The key contains two fields ({{SSN, ORGID}})
So the fields *ssn, orgId* of value type {{Person}} is not used in queries.
The right example is
{code}
IgniteCache cache = cln.cache("SQL_PUBLIC_" + CACHE_NAME);
Collection<GridQueryTypeDescriptor> types = cln.context().query().types("SQL_PUBLIC_" + CACHE_NAME);
GridQueryTypeDescriptor type = types.iterator().next();
BinaryObjectBuilder keyBuilder = cln.binary().builder(type.keyTypeName());
keyBuilder.setField("SSN", new byte[] {1, 2});
keyBuilder.setField("ORGID", new byte[] {3, 4});
cache.put(keyBuilder.build(), new Person(null, null, new byte[] {5, 6}));
{code}
Also you can use separate class for value e.g.
{code}
/** */
public static class PersonValue {
/** Name. */
@GridToStringInclude
private final byte[] name;
/** Constructor. */
public PersonValue(byte[] name) {
this.name = name;
}
/** {@inheritDoc} */
@Override public String toString() {
return S.toString(PersonValue.class, this);
}
}
{code}
> JDBC thin client selects NULL cache ID values of entries added with Java API
> ----------------------------------------------------------------------------
>
> Key: IGNITE-7411
> URL: https://issues.apache.org/jira/browse/IGNITE-7411
> Project: Ignite
> Issue Type: Bug
> Components: thin client
> Affects Versions: 2.3
> Reporter: Alexey Kukushkin
> Priority: Critical
> Attachments: Reproducer.java
>
>
> I am using SQL to create caches and run queries and DataStreamer to load lots of data. I must use MD5 digests as entity IDs (BINARY(16) SQL type). The problem is when I select data loaded with DataStreamer the fields participating in PRIMARY KEY are null.
> * Note: binary fields not part of primary keys are OK (not null)
> * Note: if I use JAVA API even the binary primary key fields are OK (not null).
> Reproducer below fails on the last assertion since SSN is NULL.
> See full reproducer code in branch ignite-7411 or use the reproducer attached.
> {code:java}
> @Test
> public void javaPutIntoSqlCacheWithBinaryAffinityKey() throws SQLException {
> try (Ignite srv = Ignition.start(getServerConfig());
> Ignite cln = Ignition.start(getClientConfig());
> Connection conn = DriverManager.getConnection("jdbc:ignite:thin://127.0.0.1/")
> ) {
> conn.prepareStatement(
> "CREATE TABLE " + CACHE_NAME + "(" +
> "ssn BINARY(16), orgId BINARY(16), name BINARY(16), PRIMARY KEY(ssn, orgId)" +
> ") WITH \"affinitykey=orgId,value_type=org.apache.ignite.Reproducer$Person\""
> ).execute();
> IgniteCache<AffinityKey<byte[]>, Person> cache = cln.cache("SQL_PUBLIC_" + CACHE_NAME);
> AffinityKey<byte[]> key = new AffinityKey<>(new byte[] {1, 2}, new byte[] {3, 4});
> cache.put(key, new Person(key.key(), key.affinityKey(), new byte[] {5, 6}));
> List<Person> entries = convert(conn.prepareStatement("SELECT * from " + CACHE_NAME).executeQuery());
> assertEquals("1 person must be in the cache", 1, entries.size());
> assertArrayEquals("Person SSN must be same as affinity key's key", key.key(), entries.get(0).getSsn());
> }
> }
> /** */
> private List<Person> convert(ResultSet resSet) throws SQLException {
> List<Person> res = new ArrayList<>();
> while (resSet.next())
> res.add(new Person(resSet.getBytes(1), resSet.getBytes(2), resSet.getBytes(3)));
> return res;
> }
> {code}
>
--
This message was sent by Atlassian JIRA
(v7.6.3#76005)