0

Jpa Repository save is working in all classes. But when trying to save in CacheWriter it is throwing NullPointerException(personRepository.save(entryEvent.getNewValue())). Any idea on this? Configured mysql database in application properties.

java.lang.NullPointerException
    at com.javasampleapproach.gemfirerestapi.GemfireWriter.beforeCreate(GemfireWriter.java:28)
    at com.gemstone.gemfire.internal.cache.LocalRegion.cacheWriteBeforePut(LocalRegion.java:3131)
    at com.gemstone.gemfire.internal.cache.AbstractRegionMap.invokeCacheWriter(AbstractRegionMap.java:3145)
    at com.gemstone.gemfire.internal.cache.AbstractRegionMap.basicPut(AbstractRegionMap.java:2909)
    at com.gemstone.gemfire.internal.cache.LocalRegion.virtualPut(LocalRegion.java:5821)
    at com.gemstone.gemfire.internal.cache.LocalRegionDataView.putEntry(LocalRegionDataView.java:118)
    at com.gemstone.gemfire.internal.cache.LocalRegion.basicPut(LocalRegion.java:5211)
    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)

Controller:

@GetMapping(value = "/getPerson")
    public Iterable<Person> getPerson(@RequestParam("id") long personId,@RequestParam("age") int age, @RequestParam("name") String name) {
        try{
            Person bob = new Person();
            bob.setPersonId(personId);
            bob.setAge(age);
            bob.setName(name);
            Region<Long,Person> region=gemfireCache.getRegion("person");
            region.put(personId, bob);

        }catch(Exception e){
            e.printStackTrace();
        }
        return personRepository.findAll();
    }

Cachewriter:

public class GemfireCacheWriter implements CacheWriter<Long, Person>{
    @Autowired
    PersonRepository personRepository;

   @Override
    public void beforeCreate(EntryEvent<Long, Person> entryEvent) throws CacheWriterException {
        // TODO Auto-generated method stub
        personRepository.save(entryEvent.getNewValue());
    }

    }

CacheWriter Config:

@Bean
    LocalRegionFactoryBean<Long, Person> personRegion(final GemFireCache cache) {
        LocalRegionFactoryBean<Long, Person> personRegion = new LocalRegionFactoryBean<>();
        personRegion.setCache(cache);
        personRegion.setName("person");
        personRegion.setPersistent(false);
        personRegion.setCacheWriter(new GemfireWriter());
        personRegion.setCacheLoader(new GemfireLoader());
        return personRegion;
    }
Bobby
  • 37
  • 5
  • I will get back to the question later, but in the meantime you should have a look at this (https://docs.spring.io/spring-boot-data-geode-build/1.1.x/reference/html5/#geode-caching-provider-inline-caching) and specifically this (https://docs.spring.io/spring-boot-data-geode-build/1.1.x/reference/html5/#geode-caching-provider-inline-caching-using-spring-data-repositories). No longer is it necessary to roll your own. – John Blum Sep 11 '19 at 18:14

1 Answers1

0

Looking at the source code for LocalRegion, I don't think the entryEvent received by your CacheWriter could be null, so the actual null reference is probably personRepository. Have you correctly configured spring-data-gemfire to autowire the PersonRepository?, is the CacheWriter configured as a Spring bean (using the @Component as an example)?.

You can use the Write Through Example as a good starting point for implementing this use case.

Hope this helps. Cheers.

Juan Ramos
  • 1,421
  • 1
  • 8
  • 13
  • Hey Juan, thanks for ur answer. Pls check Cachewriter Config(Added in top). Cachewriter is all good. But problem is with personRepository only. – Bobby Sep 11 '19 at 16:15
  • Your `CacheWriter` doesn't seem to be a Spring managed bean, so the framework will never be able to automatically set the `PersonRepository` through dependency injection... you either need to declare the `CacheWriter` as a spring managed bean (add `@Component` annotation and use component scanning), declare your `CacheWriter` as a `@Bean` within the java configuration as you're currently doing with the `LocalRegionFactoryBean`, or use constructor injection and directly pass an autowired instance of `PersonRepository` when creating the `CacheWriter` through the `personRegion` method. – Juan Ramos Sep 12 '19 at 08:22