Skip to content

Use Spring Data read models

Start with the store your application already uses. Choose the JPA integration for a relational store or the MongoDB integration for MongoDB; you do not need both to use a repository:

// JPA
dependencies {
implementation("io.cratis:arc-spring-data-jpa:<version>")
}
// MongoDB
dependencies {
implementation("io.cratis:arc-spring-data-mongodb:<version>")
}

Each module includes the Arc Spring Boot starter and the corresponding Spring Data starter. Configure the chosen store through Spring Boot as usual: it still owns the datasource, entity manager, Mongo client, repository discovery, and their standard configuration.

Once Spring has discovered the application’s repository, use it as an ordinary Spring service. In a model-bound query, mark the repository parameter with @FromServices. Arc’s generated performer then obtains that dependency from the current application context rather than treating it as caller input.

@Entity
@ReadModel
public class TaskView {
@Id
public String id;
public String title;
public static List<TaskView> all(@FromServices TaskViewRepository tasks) {
return tasks.findAll();
}
}
interface TaskViewRepository extends JpaRepository<TaskView, String> { }

View Java snippet source on GitHub

In the example, the query calls the injected repository and returns its results. The Kotlin companion method and Java static method expose the same read operation; neither creates the repository or configures its store.

The same injection pattern works with MongoRepository, repository fragments, and application query services. An application bean replaces an auto-configured adapter bean of the same integration contract. Repository injection alone does not select a tenant’s storage or subscribe to changes.

Continue with the operation you need. Concept mapping is an optional branch for the chosen store, not a requirement to configure both integrations:

  • Repositories in queries and commands — consume paging, resolve a command’s current state, choose tenant-bound access, and opt into supported transactions.
  • Map JPA concepts — use attribute converters and embedded ids when a JPA model stores domain concepts.
  • Map MongoDB concepts — register concrete scalar pairs and identifier mappings when a MongoDB document stores domain concepts.
  • Observable storage snapshots — return replacement query results as storage changes, using MongoDB change streams or explicit JPA notifications.