Hello!

I am pretty confident that affinity key configuration is supported by C++.

There is one error in your configation file: you are using Simple Mapper,
but still specify package of class in question. This causes weird behavior
on Ignite side, but is trivial to fix:

<bean class="org.apache.ignite.cache.CacheKeyConfiguration">
    <property name="typeName" value="MicFc"/>
    <property name="affinityKeyFieldName" value="market"/>
</bean>

After that, I am able to put both MicFc and MicFc-typed BinaryObjects into
cache, read them in C++ code using the snippet that you have specified.

There is no need of explicit support of Affinity from C++ code side in this
case as it is handled purely from Java side.

Hope this helps,

-- 
Ilya Kasnacheev

2018-08-09 16:22 GMT+03:00 Floris Van Nee <[email protected]>:

> Just an update.. Affinity key is indeed **not** supported in C++ at the
> moment. By digging into the C++ source I found the following..
>
>
>
> core/src/impl/binary/binary_type_updater_impl.cpp
>
> line 78:
>
> rawWriter.WriteString(0); // Affinity key is not supported for now.
>
>
>
> It just always passes in a null value for affinity key.. This obviously
> leads to the error I saw, because on the Java side it tries to merge its
> valid affinity key with the null value passed from the C++ code.
>
>
>
> Does anyone know if it is on the planning to fix this? It is quite a vital
> thing to be able to choose a different mapping for your keys..
>
>
>
> -Floris
>
>
>
> *From:* Floris Van Nee
> *Sent:* Thursday 09 August 2018 11:26 AM
> *To:* [email protected]
> *Subject:* RE: affinity key field not recognized c++ [External]
>
>
>
> Thanks for your reply. It is indeed the case that both Java and C++
> configuration files are the same, and the AffinityKeyMapped annotation is
> not used in the Java declaration. Still, it is throwing an error.
>
> I have attached here a minimal reproducing example.
>
>
>
> My Java key class is the following:
>
>
>
> public class MicFc implements Binarylizable, Comparable<MicFc> {
>
>         public String market;
>
>         public String feedcode;
>
>
>
>         @Override
>
>         public int compareTo(MicFc t) {
>
>             int m = market.compareTo(t.market);
>
>             return m == 0 ? feedcode.compareTo(t.feedcode) : m;
>
>         }
>
>
>
>         @Override
>
>         public void readBinary(BinaryReader reader) throws
> BinaryObjectException {
>
>             market = reader.readString("market");
>
>             feedcode = reader.readString("feedcode");
>
>         }
>
>
>
>         @Override
>
>         public void writeBinary(BinaryWriter writer) throws
> BinaryObjectException {
>
>             writer.writeString("market", market);
>
>             writer.writeString("feedcode", feedcode);
>
>         }
>
> }
>
>
>
> My configuration file (the same everywhere):
>
>
>
>         <property name="cacheKeyConfiguration">
>
>                                                 <list>
>
>                                                                 <bean
> class="org.apache.ignite.cache.CacheKeyConfiguration">
>
>
> <property name="typeName" value="org.apache.ignite.examples.streaming.MicFc"/>
>
>
>
> <property name="affinityKeyFieldName" value="market"/>
>
>                                                                 </bean>
>
>                                                 </list>
>
>         </property>
>
>
>
>         <property name="binaryConfiguration">
>
>             <bean class="org.apache.ignite.configuration.
> BinaryConfiguration">
>
>                 <property name="compactFooter" value="false"/>
>
>
>
>                 <property name="idMapper">
>
>                     <bean class="org.apache.ignite.
> binary.BinaryBasicIdMapper">
>
>                         <property name="lowerCase" value="true"/>
>
>                     </bean>
>
>                 </property>
>
>
>
>                 <property name="nameMapper">
>
>                     <bean class="org.apache.ignite.
> binary.BinaryBasicNameMapper">
>
>                         <property name="simpleName" value="true"/>
>
>                     </bean>
>
>                 </property>
>
>
>
>                 <property name="classNames">
>
>                     <list>
>
>                         <value>org.apache.ignite.
> examples.streaming.MicFc</value>
>
>                     </list>
>
>                 </property>
>
>             </bean>
>
>         </property>
>
>
>
> And my C++ key class:
>
> namespace
>
> {
>
> class MicFc
>
> {
>
> public:
>
>                 std::string market, feedcode;
>
> };
>
> }
>
> namespace ignite
>
> {
>
> namespace binary
>
> {
>
> IGNITE_BINARY_TYPE_START(MicFc)
>
>                 IGNITE_BINARY_GET_TYPE_ID_AS_HASH(MicFc)
>
>                 IGNITE_BINARY_GET_TYPE_NAME_AS_IS(MicFc)
>
>                 IGNITE_BINARY_GET_FIELD_ID_AS_HASH
>
>                 IGNITE_BINARY_IS_NULL_FALSE(MicFc)
>
>                 IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(MicFc)
>
>
>
>                 static void Write(BinaryWriter& writer, const MicFc& obj)
>
>                 {
>
>                                 writer.WriteString("market", obj.market);
>
>                                 writer.WriteString("feedcode",
> obj.feedcode);
>
>                 }
>
>
>
>                 static void Read(BinaryReader& reader, MicFc& dst)
>
>                 {
>
>                                 dst.market = reader.ReadString("market");
>
>                                 dst.feedcode =
> reader.ReadString("feedcode");
>
>                 }
>
>
>
> IGNITE_BINARY_TYPE_END
>
> }
>
> }
>
>
>
> To reproduce the error, first start a server with the config mentioned
> above and then run a C++ client with the same config (except for setting
>  clientMode=true) and then run the following code:
>
> MicFc mfc;
>
> mfc.market = “TEST”;
>
> mfc.feedcode=”TEST”;
>
> auto c = ignite.GetOrCreateCache<MicFc, int>("test");
>
> auto contains = c.ContainsKey(mfc); // this line throws the error
>
> Java exception occurred [cls=org.apache.ignite.binary.BinaryObjectException,
> msg=Binary type has different affinity key fields [typeName=MicFc,
> affKeyFieldName1=market, affKeyFieldName2=null]]
>
>
>
> -Floris
>
>
>
> *From:* Ilya Kasnacheev [mailto:[email protected]
> <[email protected]>]
> *Sent:* Thursday 09 August 2018 11:09 AM
> *To:* [email protected]
> *Subject:* Re: affinity key field not recognized c++ [External]
>
>
>
> Hello!
>
>
>
> As far as my understanding goes, you have to supply cacheKeyConfiguration
> in both Java and C++ configuration files, and remove @AffinityKeyMapped
> from Java CustomKey class (or other ways of specifying it where applicable).
>
>
>
> Regards,
>
>
> --
>
> Ilya Kasnacheev
>
>
>
> 2018-08-09 10:50 GMT+03:00 Floris Van Nee <[email protected]>:
>
> Hi all,
>
>
>
> I’m experiencing exactly the same issue as is described in a previous post
> on this mailing list: http://apache-ignite-users.
> 70518.x6.nabble.com/Affinity-Key-field-is-not-identified-
> if-binary-configuration-is-used-on-cache-key-object-td15959.html
>
> In short – defining an XML config with the appropriate binaryConfiguration
> (for Java/C++ interopability) and cacheKeyConfiguration (to define an
> affinityKeyFieldName for a certain key type) will fail when running from
> C++. Unfortunately, the earlier item on the mailing list didn’t find/post a
> solution to the problem.
>
>
>
> My custom key type is a class with two String members. I get the following
> error when I try to retrieve something from the cache:
>
>
>
> An error occurred: Java exception occurred 
> [cls=org.apache.ignite.binary.BinaryObjectException,
> msg=Binary type has different affinity key fields [typeName=CustomKey,
> affKeyFieldName1=string_1, affKeyFieldName2=null]]
>
>
>
> Running exactly the same from Java works fine. Also, when I remove the
> cacheKeyConfiguration part from the XML, it runs fine in both Java and C++
> (but then this runs without the proper affinity key field of course).
>
>
>
> It seems like this is a bug, or am I missing something?
>
>
>
> -Floris
>
>
>
>
>

Reply via email to