0

我已將所有Cassandra移動到單個類中。當我嘗試在Gemfire緩存監聽器中創建CassandraOperations實例時,出現空指針異常。請幫助我解決此錯誤。使用Autowired註釋的空指針異常 - Gemfire Listerner

我沒有收到任何使用spring和cassandra的空指針異常,但在與gemfire集成時得到了此指示。

@Component 
public class CacheListener<K, V> extends CacheListenerAdapter<K, V> implements Declarable { 

@Autowired 
private CassandraOperations cassandraOperations; 

@Override 
public void init(Properties props) { 

} 

public void afterCreate(EntryEvent e) { 
    cassandraOperations.insert(e.getNewValue()); 

} 

@Override 
public void close() { 
} 

} 



public class CassandraConfig { 
@Autowired 
private Environment environment; 
private static final Logger LOGGER = LoggerFactory.getLogger(CassandraConfig.class); 
@Bean 
public CassandraClusterFactoryBean cluster() { 
    CassandraClusterFactoryBean cluster = new CassandraClusterFactoryBean(); 
    cluster.setContactPoints(environment.getProperty("cassandra.contactpoints")); 
    cluster.setPort(Integer.parseInt(environment.getProperty("cassandra.port"))); 
    return cluster; 
} 
@Bean 
public CassandraMappingContext mappingContext() { 
    BasicCassandraMappingContext mappingContext = new BasicCassandraMappingContext(); 
    mappingContext.setUserTypeResolver(new SimpleUserTypeResolver(cluster().getObject(), environment.getProperty("cassandra.keyspace"))); return mappingContext; 
} 
@Bean 
public CassandraConverter converter() { 
    return new MappingCassandraConverter(mappingContext()); 
} 
@Bean 
public CassandraSessionFactoryBean session() throws Exception { 
    CassandraSessionFactoryBean session = new CassandraSessionFactoryBean(); 
    session.setCluster(cluster().getObject()); 
    session.setKeyspaceName(environment.getProperty("cassandra.keyspace")); 
    session.setConverter(converter()); 
    session.setSchemaAction(SchemaAction.NONE); 
    return session; 
} 
@Bean 
public CassandraOperations cassandraTemplate() throws Exception { 
    return new CassandraTemplate(session().getObject()); 
} 
} 

異常

[error 2017/05/05 11:16:04.874 CDT <http-nio-7878-exec-1> tid=0x5b] Exception occurred in CacheListener 
java.lang.NullPointerException 
    at CacheListener.afterCreate(CacheListener.java:27) 
    at com.gemstone.gemfire.internal.cache.EnumListenerEvent$AFTER_CREATE.dispatchEvent(EnumListenerEvent.java:97) 
    at com.gemstone.gemfire.internal.cache.LocalRegion.dispatchEvent(LocalRegion.java:8897) 
    at com.gemstone.gemfire.internal.cache.LocalRegion.dispatchListenerEvent(LocalRegion.java:7376) 
    at com.gemstone.gemfire.internal.cache.LocalRegion.invokePutCallbacks(LocalRegion.java:6158) 
    at com.gemstone.gemfire.internal.cache.EntryEventImpl.invokeCallbacks(EntryEventImpl.java:1919) 
    at com.gemstone.gemfire.internal.cache.ProxyRegionMap$ProxyRegionEntry.dispatchListenerEvents(ProxyRegionMap.java:548) 
    at com.gemstone.gemfire.internal.cache.LocalRegion.basicPutPart2(LocalRegion.java:6012) 
    at com.gemstone.gemfire.internal.cache.ProxyRegionMap.basicPut(ProxyRegionMap.java:232) 
    at com.gemstone.gemfire.internal.cache.LocalRegion.virtualPut(LocalRegion.java:5824) 
    at com.gemstone.gemfire.internal.cache.LocalRegionDataView.putEntry(LocalRegionDataView.java:118) 
    at com.gemstone.gemfire.internal.cache.LocalRegion.basicPut(LocalRegion.java:5214) 
    at com.gemstone.gemfire.internal.cache.LocalRegion.validatedPut(LocalRegion.java:1597) 
    at com.gemstone.gemfire.internal.cache.LocalRegion.put(LocalRegion.java:1580) 
    at com.gemstone.gemfire.internal.cache.AbstractRegion.put(AbstractRegion.java:327) 
    at org.springframework.data.gemfire.GemfireTemplate.put(GemfireTemplate.java:189) 
    at org.springframework.data.gemfire.repository.support.SimpleGemfireRepository.save(SimpleGemfireRepository.java:84) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
+0

的可能的複製[什麼是空指針異常,怎麼解決呢?(http://stackoverflow.com/questions/218384/what-is-a-nullpointerexception-and-how -do-i-fix-it) –

+0

cassandra和spring之間沒有例外。卡桑德拉操作實例不是在gemfire listerner中創建的 – Vigneshwaran

+0

這不是重複的 – Vigneshwaran

回答

-1

什麼是不是在你的代碼顯然/上面的配置是你如何配置你的應用程序特定的,的GemFire CacheListener使用數據的GemFire)。

我看你使用註釋春@Component立體聲類型的註釋你的應用程序CacheListener,但這並沒有什麼幫助。

您是否使用Spring的Classpath component scanning功能,或者Spring的Annotation-based container configuration支持?如果您使用的是後者,那麼您知道您仍然必須在config(JavaConfig或XML)中明確定義您的應用程序CacheListener,對不對?

當你在一個@Autowired組件/合作者場遇到NullPointerException注入的依賴,使用Spring的@Autowired註釋尤其當,這是很好的跡象,你有配置問題,特別是因爲@Autowired註釋意味着「依賴「(例如CassandraOperations)是」 需要「(除非你明確設置@Autowired註釋的required屬性,你沒有; required默認爲真正)。

因此,如果CacheListener組分被加入到掃描拾取並依賴性不能被注射(自動有線),因爲指定的類型的無(其他)豆(例如CassandraOperations)在春季應用程序定義上下文(它是),然後春天會在評估你的配置類時引發異常。

雖然,即使你CassandraConfig類也必須用Spring的@Configuration批註或與@Component註釋使用或者組件的Classpath掃描或基於註解的容器配置時進行註釋。或者,如果兩者都不使用,則必須將其明確定義爲應用程序上下文中的bean。

注意:命名約定(即CacheListener)不是很好,因爲它與GemFire自己的CacheListener接口發生衝突。這將是更好的將自己的應用專用的擴展/實現也許,「GemFireToCassandraCacheListener

舉例來說...

import ...; 

@Configuration 
class GemFireConfiguration { 

    @Bean 
    CacheFactoryBean gemfireCache() { 
    return new CacheFactoryBean(); 
    } 

    @Bean("CassandraCache") 
    PartitionedRegionFactoryBean cassandraCacheRegion() { 
    PartitionedRegionFactoryBean cassandraCacheRegion = 
     new PartitionedRegionFactoryBean(); 

    cassandraCacheRegion.setCache(gemfireCache()); 
    cassandraCacheRegion.setClose(false); 
    cassandraCacheRegion.setCacheListeners(
     new CacheListener[] { gemfireToCassandraCacheListener() }); 

    return cassandraCacheRegion; 
    } 

    @Bean 
    GemFireToCassandraCacheListener gemfireToCassandraCacheListener() { 
    return new GemFireToCassandraCacheListener(); 
    } 
} 

import ...; 

@Configuration 
class CassandraConfig { 

    // what you have above 
} 

我有很多的GemFire配置實例here,顯示了GemFire本地配置與春季(數據的GemFire)配置,XML與JavaConfig與註解,等等,等等

最後...

從技術上講,它可能是更好地使用連接到Region的GemFire CacheWriter而不是CacheListener,因爲您正在做什麼(在創建緩存時更新Cassandra)是CacheWriter的預期用途。

當然,CacheListener被稱爲"after" createCacheWriter"before" create。但是,在更新「緩存」以反映數據源之前,我會說最好更新「主要的」數據源(或「真值源」)。這尤其適用於主數據源中存在可能導致更新失敗的約束條件。如果主數據源不能更新,您不希望更新緩存。

一個CacheWriter結構類似於一個CacheListener,像這樣......

@Bean("CassandraCache") 
    PartitionedRegionFactoryBean cassandraCacheRegion() { 
    PartitionedRegionFactoryBean cassandraCacheRegion = 
     new PartitionedRegionFactoryBean(); 

    cassandraCacheRegion.setCache(gemfireCache()); 
    cassandraCacheRegion.setClose(false); 
    cassandraCacheRegion.setCacheWriter(gemfireToCassandraCacheWriter()); 

    return cassandraCacheRegion; 
    } 

    @Bean 
    GemFireToCassandraCacheWriter gemfireToCassandraCacheWriter(
     CassandraOperations cassandraOperations) { 

    return new GemFireToCassandraCacheWriter(cassandraOperations); 
    } 

GemFireToCassandraCacheWriter將被定義爲...

class GemFireToCassandraCacheWriter extends CacheWriterAdapter { 

    private CassandraOperations cassandraOperations; 

    // Using constructor injection is better than field injection 
    GemFireToCassandraCacheWriter(CassandraOperations cassandraOperations) { 
    this.cassandraOperations = cassandraOperations; 
    } 

    public void beforeCreate(EntryEvent<?, ?> event) { 
    cassandraOperations.insert(event.getNewValue()); 
    } 
} 

注:一個地區只能有1 CacheWriter。僅供參考,CacheWriter功能與CacheLoader相對應。有關更多詳細信息,請參閱GemFire User Guide。具體見here,herehere

此外,如果你只是使用了GemFire作爲狀態的緩存在卡桑德拉主要管理,那麼你也可以考慮Spring's Cache Abstraction,爲此春數據的GemFirepositions GemFire作爲一個抽象的「提供者」。

不知道你的GemFire到Cassandra UC是一切,但思考。

希望這會有所幫助!

-John