How to inject a JPARepository within SpringBoot?

Hi,

I’m new to axon, and I’m trying to understand the two different way of storing aggregate state,

  • the standard jpa repository to persist the state

  • the event sourcing repository to persist the event and get the state by replaying the events

The question is how can I make the binding of jpa repository with my aggregate?
I tried to make a configure class with @Configuration and @EnableAxon annotation, and write the below codes

@Bean
public EntityManagerProvider entityManagerProvider() {
    return new ContainerManagedEntityManagerProvider();
}

@Bean
public Repository<BankAccount> repository(){
    return new GenericJpaRepository<BankAccount>(entityManagerProvider(),BankAccount.class, eventBus());
}

@Bean
public AggregateConfigurer configurer(){
    return AggregateConfigurer.jpaMappedConfiguration(BankAccount.class, entityManagerProvider());
}

But I still getting the error saying no repository specified to my aggregate.

09:51:57.592 [main] ERROR o.s.boot.SpringApplication - Application startup failed org.springframework.context.ApplicationContextException: Failed to start bean 'org.axonframework.spring.config.AxonConfiguration'; nested exception is java.lang.IllegalStateException: Default configuration requires the use of event sourcing. Either configure an Event Store to use, or configure a specific repository implementation for class com.edi.learn.axon.aggregates.BankAccount

If I understand you correctly, you would like to configure axon for not event sourced aggregate.
You should create your jpa repository (e.g. bankAccountQueryRepository).

then you need to create Axon’s repository something like:

`

@Bean
Repository bankAccountRepository(EntityManagerProvider entityManagerProvider, EventBus eventBus) {
Repository todoRepository = new GenericJpaRepository(
entityManagerProvider,
BankAccount.class,
eventBus
);
return todoRepository;
}

`

and annotate your BankAccount with @Aggregate (if you are using spring)

beware of repository name…axon expects “aggregate root name”+Repository so it’s name needs to be in this case bankAccountRepository. If you want to change name of repository, then you should provide it in @Aggregate annotation as parameter repository.

you can take a look here I was trying to achieve the same (note maven tests are failing).

Hi,
Thanks for your reply.

axon expects “aggregate root name”+Repository so it’s name needs to be in this case bankAccountRepository

This is the key. I was struggled on this for the last couple of hours and got the same result accidentally, pity on me not seeing your answer in time :frowning:

BTW, in the sample https://github.com/AxonFramework/Axon-trader, it uses a complex object as the aggregateIdentifier

@AggregateIdentifier
private CompanyId companyId;

By using @EmbeddedId & @Embedable annotation of JPA, I’m able to save the instance into the repository.
But, I found by default, the GenericJpaRepository is using String as the type of identifier, so when loading the aggregate from the repository, the below exception will be thrown.

java.lang.IllegalArgumentException: Provided id of the wrong type for class com.edi.learn.axon.aggregates.BankAccount. Expected: class com.edi.learn.axon.domain.AccountId, got class java.lang.String

Since you’re trying to achieve the same thing, maybe you would encounter the same issue.
My solution is provide a getter and setter method for the identifier and annotated on the getter method instead of the field itself.

@Id
public String getCompanyId() {
    return companyId.toString();
}

public void setCompanyId(String companyId) {
    this.companyId= new CompanyId(companyId);
}

This would avoid implementing a custom repository, which is a complex work to do.
在 2017年3月10日星期五 UTC+8下午4:43:18,Lukáš Vasek写道:

Hi,

when i use your solution (spécific getter/setter for the id, i only have the primary key in my table.
Other columns are not created even if i put a @Colum.

Will you encoutred the same problem ?

`

@Aggregate
@Entity
@NoArgsConstructor
public class Publication
{
@AggregateIdentifier
private PublicationID publicationID;

@Id
public String getPublicationID() {
return publicationID.toString();
}
public void setPublicationID(String uuid) {
this.publicationID = new PublicationID(uuid);
}

@Column
private String libelle;

@Column
private String referenceSelsia;

@Column
private String demandeur;

…}

`

Thanks

Hi,

You need to create getter/setter for every field, and annotate @Column on the getter methoder.

在 2017年3月11日星期六 UTC+8上午7:36:28,Philippe Da Costa写道:

Hi,

thanks for your help, it works like a charm :slight_smile:

Bye