Ah thank you very much! That indeed fixes the problem. All the examples I could find had the full name specified there and since the classNames property were also full names, I never thought of changing this to the simple name. Apparently putting the full name there, triggers this strange behavior that the C++ code wants to send an updated type metadata to the Java code, causing this null error.
Thanks a lot again for the help! -Floris From: Ilya Kasnacheev [mailto:[email protected]] Sent: Thursday 09 August 2018 4:48 PM To: [email protected] Subject: Re: affinity key field not recognized c++ [External] 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]<mailto:[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]<mailto:[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]] Sent: Thursday 09 August 2018 11:09 AM To: [email protected]<mailto:[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]<mailto:[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
