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