在 .net 客户端的 Hazelcast 中使用 IPredicate 查询 Map.Values()
Querying Map.Values() by using IPredicate in Hazelcast in .net client
Hazelcast 支持团队的一名成员告诉我,我需要使用 IPortable 实现才能在 Map.Values() 中使用 IPredicate 查询。
我可以成功地将值映射到地图中,还可以使用 Map.Values()
获取所有值。请参阅下面的示例代码。
但是,当我尝试使用 SqlPredicate 查询 Map.Values() 时,我收到一条错误消息:
"An unhandled exception of type 'Hazelcast.Core.QueryException occured in Hazelcast.Net.dll'. Additional information: java.lang.IllegalStateException: Field count[2] in stream does not match ClassDefinition{factoryId=1, classId=1, version=0, fieldDefinitions=[FieldDefinitionImpl{index=0, fieldName='Name', type=UTF,..."
我的配置:
var clientConfig = new ClientConfig();
clientConfig.GetNetworkConfig().AddAddress(hazelCastIpAddress);
clientConfig.SetGroupConfig(new GroupConfig(groupId, password));
clientConfig.GetSerializationConfig().AddPortableFactory(MyDataSerializableFactory.FactoryId, new MyDataSerializableFactory());
我的 Hazelcast 存储库:
private IHazelcastInstance _hazelcastClient;
public IMap<object, TEntity> Map { get; }
public HazelCastRepository(IHazelcastInstance hazelcastClient)
{
_hazelcastClient = hazelcastClient;
Map = hazelcastClient.GetMap<object, TEntity>(typeof(TEntity).Name);
}
public void Create(TEntity entity)
{
Map.Set(entity.MapKey, entity); // map sets correctly with MapKey
}
public ICollection<TEntity> Get(string where)
{
var x = Map.Values(); // get all values and it works properly
var y = new EqualPredicate("Id", 6);
return Map.Values(y); // code breaks here with an error java.lang.IllegalStateException bla bla...
}
IPortableFactory 实现:
public class MyDataSerializableFactory : IPortableFactory
{
public const int FactoryId = 1;
public IPortable Create(int classId)
{
var type = HazelcastContext.Models[classId];
var instance = Activator.CreateInstance(type);
return (IPortable)instance;
}
}
public class HazelcastContext
{
public static Dictionary<int, Type> Models = new Dictionary<int, Type>() {
{ 1, typeof(MyTestModel)},
{ 2, typeof(MySecondTestModel) }
};
}
我的对象class:
public class MyTestModel: IPortable
{
public string Name { get; set; }
public long Id { get; set; }
public Guid MapKey
{
get; set;
} = Guid.NewGuid();
public int GetClassId()
{
return 1;
}
public int GetFactoryId()
{
return 1;
}
public void ReadPortable(IPortableReader reader)
{
Name = reader.ReadUTF("Name");
Id = reader.ReadLong("Id");
}
public void WritePortable(IPortableWriter writer)
{
writer.WriteUTF("Name", Name);
writer.WriteLong("Id", Id);
}
}
前来报错的朋友,我有办法解决这个问题
我通过 gitter.im 房间联系了 hazelcast 的支持团队,得到了一些建议,但对我没有帮助。 Mastering Hazelcast IMDB中有一段说:
The getFactoryId should return a unique positive number, and the getId should return a unique positive number within its corresponding PersonDataSerializableFactory
. Thus, IdentifiedDataSerializable
implementations can return the same ID as long as the getFactoryId is different.
所以,问题是 factoryId。如果您遇到这样的错误,请清除您在 hazelcast 上的数据并更改您使用的 factoryId。然后 hazelcast 就可以了。
我相信这是因为我在 hazelcast 上做了很多测试,因为非常 "fragile",不知何故她感到困惑。
Hazelcast 支持团队的一名成员告诉我,我需要使用 IPortable 实现才能在 Map.Values() 中使用 IPredicate 查询。
我可以成功地将值映射到地图中,还可以使用 Map.Values()
获取所有值。请参阅下面的示例代码。
但是,当我尝试使用 SqlPredicate 查询 Map.Values() 时,我收到一条错误消息:
"An unhandled exception of type 'Hazelcast.Core.QueryException occured in Hazelcast.Net.dll'. Additional information: java.lang.IllegalStateException: Field count[2] in stream does not match ClassDefinition{factoryId=1, classId=1, version=0, fieldDefinitions=[FieldDefinitionImpl{index=0, fieldName='Name', type=UTF,..."
我的配置:
var clientConfig = new ClientConfig();
clientConfig.GetNetworkConfig().AddAddress(hazelCastIpAddress);
clientConfig.SetGroupConfig(new GroupConfig(groupId, password));
clientConfig.GetSerializationConfig().AddPortableFactory(MyDataSerializableFactory.FactoryId, new MyDataSerializableFactory());
我的 Hazelcast 存储库:
private IHazelcastInstance _hazelcastClient;
public IMap<object, TEntity> Map { get; }
public HazelCastRepository(IHazelcastInstance hazelcastClient)
{
_hazelcastClient = hazelcastClient;
Map = hazelcastClient.GetMap<object, TEntity>(typeof(TEntity).Name);
}
public void Create(TEntity entity)
{
Map.Set(entity.MapKey, entity); // map sets correctly with MapKey
}
public ICollection<TEntity> Get(string where)
{
var x = Map.Values(); // get all values and it works properly
var y = new EqualPredicate("Id", 6);
return Map.Values(y); // code breaks here with an error java.lang.IllegalStateException bla bla...
}
IPortableFactory 实现:
public class MyDataSerializableFactory : IPortableFactory
{
public const int FactoryId = 1;
public IPortable Create(int classId)
{
var type = HazelcastContext.Models[classId];
var instance = Activator.CreateInstance(type);
return (IPortable)instance;
}
}
public class HazelcastContext
{
public static Dictionary<int, Type> Models = new Dictionary<int, Type>() {
{ 1, typeof(MyTestModel)},
{ 2, typeof(MySecondTestModel) }
};
}
我的对象class:
public class MyTestModel: IPortable
{
public string Name { get; set; }
public long Id { get; set; }
public Guid MapKey
{
get; set;
} = Guid.NewGuid();
public int GetClassId()
{
return 1;
}
public int GetFactoryId()
{
return 1;
}
public void ReadPortable(IPortableReader reader)
{
Name = reader.ReadUTF("Name");
Id = reader.ReadLong("Id");
}
public void WritePortable(IPortableWriter writer)
{
writer.WriteUTF("Name", Name);
writer.WriteLong("Id", Id);
}
}
前来报错的朋友,我有办法解决这个问题
我通过 gitter.im 房间联系了 hazelcast 的支持团队,得到了一些建议,但对我没有帮助。 Mastering Hazelcast IMDB中有一段说:
The getFactoryId should return a unique positive number, and the getId should return a unique positive number within its corresponding
PersonDataSerializableFactory
. Thus,IdentifiedDataSerializable
implementations can return the same ID as long as the getFactoryId is different.
所以,问题是 factoryId。如果您遇到这样的错误,请清除您在 hazelcast 上的数据并更改您使用的 factoryId。然后 hazelcast 就可以了。
我相信这是因为我在 hazelcast 上做了很多测试,因为非常 "fragile",不知何故她感到困惑。