Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Caching Gemfire缓存引发PartionedRegionException:对象哈希代码在对等方之间不一致_Caching_Gemfire_Spring Data Gemfire - Fatal编程技术网

Caching Gemfire缓存引发PartionedRegionException:对象哈希代码在对等方之间不一致

Caching Gemfire缓存引发PartionedRegionException:对象哈希代码在对等方之间不一致,caching,gemfire,spring-data-gemfire,Caching,Gemfire,Spring Data Gemfire,当在gemfire中使用分区缓存并使用可缓存注释与spring数据集成时,它会将数据正确地放入缓存中,但当从缓存中检索时,如果密钥位于不同的分区上,则会引发PartitionedRegionException,表示缓存对等方之间的哈希代码不一致。我已经重写了类中的equals和hashCode方法,该类的对象是缓存的键。知道我哪里会出错吗?两个缓存对等点位于同一台计算机上。定位器从外部启动。 我正在使用以下方法启动缓存 @Bean @Primary Cache getGemfireCache(

当在gemfire中使用分区缓存并使用可缓存注释与spring数据集成时,它会将数据正确地放入缓存中,但当从缓存中检索时,如果密钥位于不同的分区上,则会引发PartitionedRegionException,表示缓存对等方之间的哈希代码不一致。我已经重写了类中的equals和hashCode方法,该类的对象是缓存的键。知道我哪里会出错吗?两个缓存对等点位于同一台计算机上。定位器从外部启动。 我正在使用以下方法启动缓存

@Bean
@Primary 
Cache getGemfireCache() {
Cache cache = new CacheFactory().create();
RegionFactory<Object,Object> regionFactory = cache.createRegionFactory(RegionShortcut.PARTITION);
allCacheNames.forEach(cacheName -> regionFactory.create(cacheName));
return cache;
} 

@Bean
@初级的
缓存getGemfireCache(){
Cache Cache=new CacheFactory().create();
RegionFactory RegionFactory=cache.createRegionFactory(RegionShortcut.PARTITION);
所有cacheName.forEach(cacheName->regionFactory.create(cacheName));
返回缓存;
} 
任何帮助都将不胜感激

谢谢

Hmmm

首先,很难准确地描述您遇到的问题,但我几乎可以肯定,与Spring数据相比,它与Spring数据的关系很小,或者在技术上,在这种情况下(特别是因为您提到了使用注释的“缓存”),而与Pivotal GemFire本身的关系不大,或者更可能与您的应用程序域模型的关系不大

其次,您遇到的问题与上面显示的配置关系不大。基本上,在您的配置中,您正在为应用程序服务方法上声明的
@Cacheable
注释中标识的每个缓存创建一个“对等”
缓存
实例以及
区域
,在本例中,这不是特别有趣的


提示:关于配置,最好这样做:

@springboot应用程序
@EnableCachingDefinedRegions
公共类MyCachingSpringBootApplication{…}
有关详细信息,请参见和

注意:默认情况下,SBDG创建一个
ClientCache
实例,而不是一个“对等”
Cache
实例。如果您确实希望Spring应用程序包含嵌入式对等
缓存
实例并成为服务器集群的一部分,那么您还可以通过声明
@peerCache
注释来覆盖SBDG自动配置
客户端缓存
实例的首选项。有关更多详细信息,请参阅


接下来,您提到您“覆盖”了equals和hashCode,这似乎表明您正在使用一些复杂的键。一般来说,在使用GemFire时,最好使用简单的键类型,例如
Long
Integer
String
,等等,原因与您的经历类似

如果您需要影响整个集群的分区策略或数据组织(例如,可能用于配置),那么更好的选择是实现GemFire并向PR注册

但是,可缓存服务方法的外观如下所示并不少见:

@Cacheable(“CustomerByAccount”)
由(客户){…}查找的帐户
您可能很清楚,上面显示的
@Cacheable
“findBy”服务方法的“key”是
Customer
,这显然是一个复杂的对象,当用作GemFire缓存区域中的key时,必须具有有效的
等于
hashCode
方法,用于支持应用程序缓存“CustomerByAccount”

有几个问题:

  • A)您的复杂密钥的类定义(如
    Customer
    )是否可能发生更改,例如通过添加/删除[new]字段或更改字段类型(?),以及B)支持缓存的分区区域(如“CustomerByAccount”)是否持久

  • 您的
    equals
    hashCode
    方法是否一致?也就是说,它们声明并使用相同的字段来确定
    equals
    hashCode
    的结果

  • 例如,这是无效的:

    class客户{
    私人长id;
    私有字符串名;
    私有字符串lastName;
    ...
    @凌驾
    公共布尔等于(对象obj){
    if(this==obj){
    返回true;
    }
    如果(!(客户的obj实例)){
    返回false;
    }
    客户,即=(客户)obj;
    返回this.id.equals(that.id);
    }
    @凌驾
    公共int hashCode(){
    int hashValue=17;
    hashValue=37*hashValue+this.firstName.hashCode();
    hashValue=37*hashValue+this.lastName.hashCode();
    返回哈希值;
    }
    ...
    }
    
    或者
    等于
    /
    hashCode
    的任何其他组合可能会产生不同的结果,具体取决于之前存储在GemFire中的状态

    您还可以尝试清除缓存和重新水化(根据需要急切地或懒散地),尤其是在类定义已更改的情况下,尤其是在某些类类型用作键的情况下

    此外,一般来说,如果不能严格遵循简单/标量类型(例如
    Long
    String
    ),我建议尽可能多地使用不可变键。 也许,如果您可以在应用程序域模型类中共享更多细节,比如用作键的类型,以及在服务方法上使用Spring的缓存抽象,这可能会有所帮助

    此外,任何重现该问题的示例或测试用例都将受到极大的赞赏

    谢谢