Search code examples
ignite

Apache Ignite .Net 2.8.1: Affinity collocation with QueryEntity


I'm using Apache Ignite v.2.8.1 .Net on a Windows 10 machine.

I am trying to use affinity collocation on a query-enabled cache. The entities I store in cache have a primary key named "Id" and an affinity key named "PartnerId". Both keys are of the type Int32. I'm defining the cache as follows:

new CacheConfiguration("BespokeCharge")
        {
            KeyConfiguration = new[]
            {
                    new CacheKeyConfiguration()
                    {
                        AffinityKeyFieldName = "PartnerId",
                        TypeName = typeof(BespokeCharge).Name
                    }
            }
        };

Next I use the following code to add the data:

var cache = Ignite.GetCache<AffinityKey, BespokeCharge>("BespokeCharge")
cache.Put(new AffinityKey(entity.Id, entity.PartnerId), entity)

So far so good. Since I want to be able to use SQL to search for bespoke charges, I also add a QueryEntity configuration:

new CacheConfiguration("BespokeCharge",
            new QueryEntity(typeof(AffinityKey), typeof(BespokeCharge))
            {
                KeyFieldName = "Id",
                TableName = "BespokeCharge"
            })
        {
            KeyConfiguration = new[]
            {
                    new CacheKeyConfiguration()
                    {
                        AffinityKeyFieldName = "PartnerId",
                        TypeName = typeof(BespokeCharge).Name
                    }
            }
        };

When I run the code, both Ignite and my app crash and the following error is logged:

JVM will be halted immediately due to the failure: [failureCtx=FailureContext [type=CRITICAL_ERROR, err=class o.a.i.i.processors.cache.persistence.tree.CorruptedTreeException: B+Tree is corrupted [pages(groupId, pageId)=[IgniteBiTuple [val1=1565129718, val2=844420635164729]], cacheId=-1278247946, cacheName=BESPOKECHARGES, indexName=BESPOKECHARGES_ID_ASC_IDX, msg=Runtime failure on row: Row@29db2fbe[ key: AffinityKey [idHash=8137191, hash=783909474, key=3, affKey=2], val: UtilityClick.BillValidation.Shared.InMemory.Model.BespokeCharge [idHash=889383506, hash=-399638125, BespokeChargeTypeId=4, ChargeValue=100.0000, ChargeValueIncCommission=100.0000, Id=3, PartnerId=2, QuoteRecordId=5] ][ 4, 100.0000, 100.0000, , 2, 5 ]]]]

When I tried to define QueryEntity with the key type of int instead of AffinityKey, I got a different error with the same outcome -- a crash.

JVM will be halted immediately due to the failure: [failureCtx=FailureContext [type=CRITICAL_ERROR, err=java.lang.ClassCastException: class o.a.i.cache.affinity.AffinityKey cannot be cast to class java.lang.Integer (o.a.i.cache.affinity.AffinityKey is in unnamed module of loader 'app'; java.lang.Integer is in module java.base of loader 'bootstrap')]]

What am I doing wrong? Thank you for your help!


Solution

  • KeyFieldName = "Id" setting is the problem. It sets Id field to be used as a cache key, which is int, but then we use AffinityKey as a cache key, which causes a type mismatch.

    In this case I don't think we need KeyFieldName at all, removing it fixes the problem, and SELECT queries should not be affected by this change.