apache / ignite

Apache Ignite

Home Page:https://ignite.apache.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

SQL for a cache with custom key / primitive value (ex: `ClientCache<MyCustomKey, String>`)

pasniak opened this issue · comments

I followed the documentation to create a custom (composite) key (XML below).

In my case the value is not a custom class: it's just java.lang.String..., which I would like to name/query in SQL. How do I accomplish this?

Right now the SQL table is automagically named STRING and I think there is no way to query for the value (?!)

0: jdbc:ignite:thin://127.0.0.1/> !tables
+-----------+-------------+-----------------------------+------------+
| TABLE_CAT | TABLE_SCHEM |         TABLE_NAME          | TABLE_TYPE |
+-----------+-------------+-----------------------------+------------+
| IGNITE    | PERSONCACHE | STRING                      | TABLE      |

It has no value:

0: jdbc:ignite:thin://127.0.0.1/> !columns STRING
+-----------+-------------+------------+-------------+
| TABLE_CAT | TABLE_SCHEM | TABLE_NAME | COLUMN_NAME |
+-----------+-------------+------------+-------------+
| IGNITE    | PERSONCACHE | STRING     | FIRSTNAME   |
| IGNITE    | PERSONCACHE | STRING     | LASTNAME    |
+-----------+-------------+------------+-------------+

After MyCustomKey myCustomKey = new MyCustomKey("Adam", "Edsel"); cache.put(myCustomKey, "test value");

0: jdbc:ignite:thin://127.0.0.1/> select * from personCache.STRING;
+-----------+----------+
| FIRSTNAME | LASTNAME |
+-----------+----------+
| Adam      | Edsel    |
+-----------+----------+

(how do I get "test value" by SQL?)

Below is cache configuration:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--bean id="grid.cfg" class="org.apache.ignite.configuration.IgniteConfiguration"/-->
    <bean class="org.apache.ignite.configuration.IgniteConfiguration">
        <property name="cacheConfiguration">
            <bean class="org.apache.ignite.configuration.CacheConfiguration">
                <property name="name" value="PERSONCACHE"/><-- this has to be in CAPS -->
                <!-- Configure query entities -->
                <property name="queryEntities">
                    <list>
                        <bean class="org.apache.ignite.cache.QueryEntity">
                            <!-- Registering key's class. -->
                            <property name="keyType" value="org.examples.MyKey"/>
                            <!-- Registering value's class. -->
                            <property name="valueType" value="java.lang.String"/>  <-- how do I name this column in SQL? -->
                            <!-- Defining all the fields that will be accessible from DML. -->
                            <property name="fields">
                                <map>
                                    <entry key="firstName" value="java.lang.String"/>
                                    <entry key="lastName" value="java.lang.String"/>
                                </map>
                            </property>
                            <!-- Defining the subset of key's fields -->
                            <property name="keyFields">
                                <set>
                                    <value>firstName</value>
                                    <value>lastName</value>
                                </set>
                            </property>
                        </bean>
                    </list>
                </property>
            </bean>
        </property>
    </bean>
</beans>

If I add a field which is not in the keyFields,

<entry key="description" value="java.lang.String"/>

to that configuration, it leads to Error: Failed to execute map query on remote node [nodeId=20293ae3-b385-4d9f-917f-cbe9325d5f8a, errMsg=Unexpected binary object class [type=class org.apache.ignite.internal.processors.cache.CacheObjectImpl]] (state=50000,code=1)

I figured it out. Value's SQL field name is specified in valueFieldName property:

<property name="valueFieldName" value="lastValue"/>

The SQL field has also to be present in fields map:

<entry key="lastValue" value="java.lang.String"/>

After put() ...

            ClientCache<MyCustomKey, String> cache = client.getOrCreateCache("PERSONCACHE");
            MyCustomKey myCustomKey = new MyCustomKey("Adam", "Edsel");
            cache.put(myCustomKey, "test value 2");

... the column is visible in a query result:

0: jdbc:ignite:thin://127.0.0.1/> select * from personCache.STRING;
+-----------+----------+--------------+
| FIRSTNAME | LASTNAME |  LASTVALUE   |
+-----------+----------+--------------+
| Adam      | Edsel    | test value 2 |
+-----------+----------+--------------+

Full XML:

    <bean class="org.apache.ignite.configuration.IgniteConfiguration">
        <property name="cacheConfiguration">
            <bean class="org.apache.ignite.configuration.CacheConfiguration">
                <property name="name" value="PERSONCACHE"/>
                <property name="queryEntities">
                    <list>
                        <bean class="org.apache.ignite.cache.QueryEntity">
                            <property name="keyType" value="org.examples.MyKey"/>
                            <property name="valueType" value="java.lang.String"/>
                            <property name="valueFieldName" value="lastValue"/>
                            <property name="fields">
                                <map>
                                    <entry key="firstName" value="java.lang.String"/>
                                    <entry key="lastName" value="java.lang.String"/>
                                    <entry key="lastValue" value="java.lang.String"/>
                                </map>
                            </property>
                            <property name="keyFields">
                                <set>
                                    <value>firstName</value>
                                    <value>lastName</value>
                                </set>
                            </property>
                        </bean>
                    </list>
                </property>
            </bean>
        </property>