5

I started exploring about Hazelcast functionalities and I've been trying use a MapStore as a Write-Behind buffer for my database through HazelcastRepository. My goal is to use a JpaRepository inside my MapStore to load and store to/from the cache.

I'm using Spring Boot and after doing some research i found that i could use the @SpringAware to Autowire my Repository inside MapStore but every-time it gets there my Bean is null and I get a NullPointerException. I can't get it working even after lots of different tests I was not able to Autowire my bean inside the MapStore

is something wrong with this configuration to enable SpringAware or am I looking at the wrong place?

Found This stackoverflow post and it gave me clues but I still couldn't figure out the issue since most configurations were xml and not java. Also Found this Github Issue on how to configure SpringAware in Hazelcast through Java configurations

And I committed my example code in this Git Repo Here.

Debugger Screenshot null Bean

3 Answers3

6

After investigation the provided code, I noticed that the @SpringAware was never enabled by default as per a GitHub issue I found on Hazelcast. The issue described that SpringAware was disabled because it was affecting the performance, which forwarded me to another closed ticket solving enabling the annotation by code using the SpringManagedContext (avoiding the use of XML), but it doesn't still solve the issue.

The real solution was found here, add MapLoaderLifecycleSupport interface to your MapStore implementation and implement the init method as shown in the ticket:

@Override
public void init(HazelcastInstance hazelcastInstance, Properties properties, String mapName) {
    hazelcastInstance.getConfig().getManagedContext().initialize(this);
}

This will force @SpringAware to be enabled in the MapStore class, therefore, being able to autowire any spring component into the class as shown in the image below.

working-jpa-repository-map-store-screenshot

JeriesHG
  • 76
  • 4
  • this actually worked really well, so we have to have the SpringAware and also set the context 'manually' in the init, great catch.. accepted your pull request with the fixed change – Fernando Nakano Sep 13 '18 at 20:30
  • Hi..@FernandoNakano I'm also facing similar issue.. so Can you please the git source code link..Or Any suggestions would be helpful.. – manu Nov 11 '20 at 09:58
  • for me this worked only starting from spring boot version 2.7.0 (https://github.com/spring-projects/spring-boot/pull/28801). Before managed context was not injected during auto configuration and I was getting npe. please be aware of that – Stepan Pogosyan Sep 18 '22 at 22:20
1

Here the problem is you are creating the spring bean with name pr, when auto wiring you are using personRepository.

Either change pr to personRepository in PersonRepository.java OR remove ("pr") from PersonRepository.java

@Autowired
PersonRepository personRepository; 

DAO

@Repository("pr")
public interface PersonRepository extends JpaRepository<Person, Integer> {

    @Query("SELECT id FROM Person")
    Iterable<Integer> findAllId();
}
Jobin
  • 5,610
  • 5
  • 38
  • 53
  • Good point, thanks for finding that out, this is actually something i added after doing some tests, i removed the bean name back for just @Repository but it still doesn't work, the personRepository is still null inside the MapStore. – Fernando Nakano Aug 22 '18 at 20:13
0

Lazily injecting the MapStore bean to the class where you initialise your maps works too:

    @Inject
    HazelcastConfiguration(@Lazy MyMapStore myMapStore) {
        this.myMapStore = myMapStore;
    }

In this example the MyMapStore bean contains an injected MyRepository bean.

wild_nothing
  • 2,845
  • 1
  • 35
  • 47