Currently the application on which i am working is using axon framework. I want to use caching for event repo and saga repo? And it requires cache configuration.?
Does AXON supports hazelcast cache as application using only this cache.?
Hazelcast cache implementations are not provided out of the box. If I remember well JCache and EHCache are provided.
Writing you own implementation should be fairly straight forward.
That being said, why is it you want to cache with Hazelcast?
Yes your assumption is correct. I am using Spring Boot.
To configure the CachingEventSourcingRepository, one part is to provide provide the cache part.
Before configuration:
It has configuration class something like this:
@Configuration @EnablingCaching
public class XYZHazelcastConfiguration{
// add map config for different caches into Config part of Hazelcast.
}
Below are the dependency I am using it for Hazelcast
I suppose that it requires jcache dependency. So added below dependency
javax.cache
cache-api
After this spring boot application without any error, but it is not able to find the previous cache that was working.
Even i tried this also
@Bean
org.axonframework.common.caching.Cache cache(HazelcastInstance hazelCastInstance) {
return new org.axonframework.common.caching.JCacheAdapter(hazelCastInstance.getCache(“myAxonCache”);
}
HazelcastInstance class does not have any such method like getCache.
I think that we need to get the cache from jcache manager instead of getting it from instance. But tried this, it is not working for me. It does not able to find the cache.
I also checked the example of axon trader and axon bank. Both using CachingEventSourcingRepository. But it was using default axon cache.
Thanks Frans, after adding the updated version of hazelcast 3.8.3, i am able to see this method cacheManager.
Along with this, to get JCacheConfiguration, i have added the below dependency.
javax.cache
cache-api
1.0.0
Spring boot has started throwing me this error. I think this is not related to AXON Framework. But anyways i am trying to figure it this error.
java.lang.IllegalArgumentException: Cannot find cache named ‘xyzCache’ for Builder throws caches=[xyzCache] | key=’’ | keyGenerator=’’ | cacheManager=’’ | cacheResolver=’’ | condition=’’ | unless=’’ | sync=‘false’
at org.springframework.cache.interceptor.AbstractCacheResolver.resolveCaches(AbstractCacheResolver.java:81)
at org.springframework.cache.interceptor.CacheAspectSupport.getCaches(CacheAspectSupport.java:242)
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.(CacheAspectSupport.java:675)
at org.springframework.cache.interceptor.CacheAspectSupport.getOperationContext(CacheAspectSupport.java:255)
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContexts.(CacheAspectSupport.java:581)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
at com.sun.proxy.$Proxy153.getToken(Unknown Source)
I guess the exception means that a cache must be created/defined before you can use it. Since this is not Axon related in any way, the documentation of Hazelcast should be able to help you here.
I am able to overcome the cache issue. But now I am facing the below issue. Any idea.
java.lang.IllegalArgumentException: The aggregate root is unknown. Is this entity properly registered as the child of an aggregate member?
at org.axonframework.common.Assert.isTrue(Assert.java:52)
at org.axonframework.common.Assert.notNull(Assert.java:76)
at org.axonframework.eventsourcing.AbstractEventSourcedEntity.apply(AbstractEventSourcedEntity.java:100)
at org.axonframework.eventsourcing.AbstractEventSourcedEntity.apply(AbstractEventSourcedEntity.java:86)
@Bean @Scope(“prototype”)
public MyAggregateRoot myAggregateroot() {
return new MyAggregateRoot ();
}
@Bean
public AggregateFactory aggregateFactory() {
SpringPrototypeAggregateFactory aggregateFactory =
new SpringPrototypeAggregateFactory<>();
aggregateFactory.setPrototypeBeanName(“myAggregateRoot”);
return aggregateFactory;
}
@Bean
public Cache getCache(HazelcastInstance hazelcastInstance) {
return new JCacheAdapter(
hazelcastInstance.getCacheManager().getCache(“axonEventsRepoCache”));
}
Looking at this quickly, I’m suspecting a capitalization problem.
You have : aggregateFactory.setPrototypeBeanName(“myAggregateRoot”); (upper case R in Root)
And: public MyAggregateRoot myAggregateroot() (lower case R)
There are a couple of other thing I noticed about your code: you’re separately injection an EventBus and EventStore, but in Axon3, the EventStore is a specialization of the EventBus (a special kind of bus that also stores events) so you don’t have to configure those separately. Also, you use the Spring Prototype aggregate factory, which doesn’t seem necessary since all you’re doing is invoking the default constructor. So you may be able to use a simpler config like:
@Bean("eventBus")
public EventStore eventStore(EventStorageEngine storageEngine) {
return new EmbeddedEventStore(storageEngine);
}
@Bean
public Repository<MyAggregateRoot> myAggregateRootRepository(EventStore eventStore, Cache cache) {
return new CachingEventSourcingRepository<>(new GenericAggregateFactory<>(MyAggregateRoot.class), eventStore, cache);
}
One other thing that may be an issue: for Spring autodetection of aggregates to work, they need to be annoted with @org.axonframework.spring.stereotype.Aggregate, not@org.axonframework.commandhandling.model.AggregateRoot
That tends to be confusing.
I see SpringAggregateFactory is of no use in application as we are invoking the default constructor.
Tried suggested changes but still the same. Detailed stack trace are:
java.lang.IllegalArgumentException: The aggregate root is unknown. Is this entity properly registered as the child of an aggregate member?
at org.axonframework.common.Assert.isTrue(Assert.java:52)
at org.axonframework.common.Assert.notNull(Assert.java:76)
at org.axonframework.eventsourcing.AbstractEventSourcedEntity.apply(AbstractEventSourcedEntity.java:100)
at org.axonframework.eventsourcing.AbstractEventSourcedEntity.apply(AbstractEventSourcedEntity.java:86)
at com.adsds.app.ad.core.MyEntity.method1(MyEntity.java:98)
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:497)
at org.axonframework.common.annotation.MethodMessageHandler.invoke(MethodMessageHandler.java:85)
at org.axonframework.commandhandling.annotation.AggregateCommandHandlerInspector$EntityForwardingMethodMessageHandler.invoke(AggregateCommandHandlerInspector.java:224)
at org.axonframework.commandhandling.annotation.AggregateAnnotationCommandHandler$AggregateCommandHandler.handle(AggregateAnnotationCommandHandler.java:331)
at org.axonframework.commandhandling.annotation.AggregateAnnotationCommandHandler.handle(AggregateAnnotationCommandHandler.java:277)
at org.axonframework.commandhandling.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:63)
at org.axonframework.commandhandling.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:69)
at org.axonframework.commandhandling.SimpleCommandBus.doDispatch(SimpleCommandBus.java:127)
at org.axonframework.commandhandling.SimpleCommandBus.doDispatch(SimpleCommandBus.java:103)
at org.axonframework.commandhandling.SimpleCommandBus.dispatch(SimpleCommandBus.java:75)
at org.axonframework.commandhandling.distributed.jgroups.JGroupsConnector$MessageReceiver.processDispatchMessage(JGroupsConnector.java:415)
at org.axonframework.commandhandling.distributed.jgroups.JGroupsConnector$MessageReceiver.receive(JGroupsConnector.java:405)
at org.jgroups.JChannel.up(JChannel.java:768)
Entity Class
public class MyEntity extends AbstractAnnotatedEntity
implements Serializable {
private static final long serialVersionUID = 2015112400L;
public MyEntity() { }
@CommandHandler
public MyStatus joinMyGroup(JoinGroupCommand cmd) {
apply(new JoinGroupEvent(…));
}
}
it seems you call apply() in the MyEntity’s constructor, but I can’t tell for sure. Entities should not do that, as their state is set by the event handler of their parent (in your case, GroupCallStartedEvent).
Facing some different behavior here, i tried to run the application in debug mode( inside registerAggregateRoot of AbstractEventSourcedEntity), before making the another command to get fired. And after reaching this breakpoint, I moved to another command by doing a wait of 1-2 seconds hardly at this break point. I don’t see the below exception.