Using Axon server as event store along side H2 for projection sid

I use Spring boot and axon-spring-boot-starter’, version: ‘4.7.0’ and axon server (docker) as event store and message routing.

Int the same project (POC) I include my query side and save all my projections to H2 db.
I use spring-boot-starter-jdbc dependency for simple JdbcTemplate.

I want to keep axon server as my event store and not H2 but when I start my app I get

Caused by: org.axonframework.common.jdbc.JdbcException: Failed to create a SQL statement
	at org.axonframework.common.jdbc.JdbcUtils.createSqlStatement(JdbcUtils.java:247) ~[axon-messaging-4.7.0.jar:4.7.0]
	at org.axonframework.common.jdbc.JdbcUtils.executeQuery(JdbcUtils.java:76) ~[axon-messaging-4.7.0.jar:4.7.0]
	at org.axonframework.eventhandling.tokenstore.jdbc.JdbcTokenStore.loadConfigurationToken(JdbcTokenStore.java:194) ~[axon-messaging-4.7.0.jar:4.7.0]
	at org.axonframework.eventhandling.tokenstore.jdbc.JdbcTokenStore.retrieveStorageIdentifier(JdbcTokenStore.java:187) ~[axon-messaging-4.7.0.jar:4.7.0]
	at org.axonframework.eventhandling.TrackingEventProcessor.lambda$calculateIdentifier$6(TrackingEventProcessor.java:269) ~[axon-messaging-4.7.0.jar:4.7.0]
	at org.axonframework.common.transaction.TransactionManager.fetchInTransaction(TransactionManager.java:70) ~[axon-messaging-4.7.0.jar:4.7.0]
	at org.axonframework.eventhandling.TrackingEventProcessor.calculateIdentifier(TrackingEventProcessor.java:268) ~[axon-messaging-4.7.0.jar:4.7.0]
	at org.axonframework.eventhandling.TrackingEventProcessor.lambda$getTokenStoreIdentifier$5(TrackingEventProcessor.java:264) ~[axon-messaging-4.7.0.jar:4.7.0]
	at java.base/java.util.concurrent.atomic.AtomicReference.updateAndGet(AtomicReference.java:209) ~[na:na]
	at org.axonframework.eventhandling.TrackingEventProcessor.getTokenStoreIdentifier(TrackingEventProcessor.java:264) ~[axon-messaging-4.7.0.jar:4.7.0]
	at org.axonframework.axonserver.connector.processor.StreamingEventProcessorInfoMessage.describe(StreamingEventProcessorInfoMessage.java:58) ~[axon-server-connector-4.7.0.jar:4.7.0]
	at org.axonframework.axonserver.connector.processor.EventProcessorControlService.lambda$infoSupplier$1(EventProcessorControlService.java:120) ~[axon-server-connector-4.7.0.jar:4.7.0]
	at io.axoniq.axonserver.connector.impl.ControlChannelImpl.lambda$sendScheduledProcessorInfo$3(ControlChannelImpl.java:248) ~[axonserver-connector-java-4.6.3.jar:4.6.3]
	at java.base/java.util.concurrent.ConcurrentHashMap$ValuesView.forEach(ConcurrentHashMap.java:4772) ~[na:na]
.....
....
Caused by: org.h2.jdbc.JdbcSQLSyntaxErrorException: Table "TOKENENTRY" not found; SQL statement:
SELECT processorName, segment, token, tokenType, timestamp, owner FROM TokenEntry WHERE processorName = ? AND segment = ?  [42102-214]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:502) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:477) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.message.DbException.get(DbException.java:223) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.message.DbException.get(DbException.java:199) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.getTableOrViewNotFoundDbException(Parser.java:8398) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.getTableOrViewNotFoundDbException(Parser.java:8369) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.readTableOrView(Parser.java:8358) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.readTablePrimary(Parser.java:1863) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.readTableReference(Parser.java:2334) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parseSelectFromPart(Parser.java:2772) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parseSelect(Parser.java:2878) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parseQueryPrimary(Parser.java:2762) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parseQueryTerm(Parser.java:2633) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parseQueryExpressionBody(Parser.java:2612) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parseQueryExpressionBodyAndEndOfQuery(Parser.java:2605) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parseQueryExpression(Parser.java:2598) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parseQuery(Parser.java:2567) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parsePrepared(Parser.java:724) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parse(Parser.java:689) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.parse(Parser.java:661) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.command.Parser.prepareCommand(Parser.java:569) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.engine.SessionLocal.prepareLocal(SessionLocal.java:631) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.engine.SessionLocal.prepareCommand(SessionLocal.java:554) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1116) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:92) ~[h2-2.1.214.jar:2.1.214]
	at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:288) ~[h2-2.1.214.jar:2.1.214]
	at com.zaxxer.hikari.pool.ProxyConnection.prepareStatement(ProxyConnection.java:337) ~[HikariCP-4.0.3.jar:na]

Before adding spring-boot-starter-jdbc everything worked fine

Hi Eyal,

You need a few tables to store the projections to H2. When JDBC is used, a JDBC token store will be created for you. This way the projections and the tokens are stored in the same database, ensuring consistency.

You can find some SQL to create the tables needed here, alternatively you could switch to use JPA instead, and have the tables auto generated via hibernate.

1 Like

Thank you. I thought to myself that tables are mandatory only if one chooses RDBMS as event store only. Now I see it is mandatory for projection part.
Thank you

I copied and paste what from the link but I still get

ERROR: relation “tokenentry” does not exist

First, a clarification, the error has nothing to do with projections. It is about not finding a table for the token store.

Since you said you “copied and paste what from the link” I guess the error is because the code you pasted creates token_entry table while your app looks for tokenentry table.

Check your token store configuration and ensure you have the tables the configuration expects.

1 Like

Strictly speaking you don’t really need the tokenentry table. Especially if you just use it for local development now, you define a Spring bean to use the InMemoryTokenStore instead of the JdbcTokenStore that’s currently auto wired.

It does mean on every restart the event processors wil read all the events again. By storing the tokens together with the projection, this is prevented.

1 Like

Another option is to add annotation

@RegisterDefaultEntities(
        packages = {
                "org.axonframework.eventsourcing.eventstore.jpa"
        }
)

and also

 spring:
   jpa:
    hibernate:
      ddl-auto: update