ignite-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Floris Van Nee <florisvan...@Optiver.com>
Subject RE: affinity key field not recognized c++
Date Thu, 09 Aug 2018 15:14:31 GMT
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:ilya.kasnacheev@gmail.com]
Sent: Thursday 09 August 2018 4:48 PM
To: user@ignite.apache.org
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 <florisvannee@optiver.com<mailto:florisvannee@optiver.com>>:
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: user@ignite.apache.org<mailto:user@ignite.apache.org>
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:ilya.kasnacheev@gmail.com]
Sent: Thursday 09 August 2018 11:09 AM
To: user@ignite.apache.org<mailto:user@ignite.apache.org>
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 <florisvannee@optiver.com<mailto:florisvannee@optiver.com>>:
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



Mime
View raw message