@@ -95,7 +95,7 @@ public class Fruit {
95
95
96
96
As stated above, we are using the DataStax Object Mapper. In other words, we are not going to write
97
97
our CQL queries manually; instead, we will annotate our data model with a few annotations, and the
98
- mapper will generate proper CQL queries underneath.
98
+ mapper will generate proper CQL queries for us underneath.
99
99
100
100
This is why the `Fruit` class is annotated with `@Entity`: this annotation marks it as an _entity
101
101
class_ that is mapped to a Cassandra table. Its instances are meant to be automatically persisted
@@ -131,7 +131,7 @@ Note also the special return type of the `findAll` method,
131
131
link:https://docs.datastax.com/en/drivers/java/latest/com/datastax/oss/driver/api/core/PagingIterable.html[`PagingIterable`]:
132
132
it's the base type of result sets returned by the driver.
133
133
134
- Finally, let's create the a Mapper interface:
134
+ Finally, let's create a Mapper interface:
135
135
136
136
[source,java]
137
137
----
@@ -146,6 +146,96 @@ The `@Mapper` annotation is yet another annotation recognized by the DataStax Ob
146
146
mapper is responsible for constructing instances of DAOs – in this case, out mapper is constructing
147
147
an instance of our only DAO, `FruitDao`.
148
148
149
+ Think of the mapper interface as a factory for DAO beans: if you intend to construct and inject a
150
+ specific DAO bean in your own code, then you first need to add a `@DaoFactory` method for it in a
151
+ `@Mapper` interface.
152
+
153
+ TIP: `@DaoFactory` method names are irrelevant.
154
+
155
+ `@DaoFactory` methods should return beans of the following types:
156
+
157
+ - Any `@Dao`-annotated interface, e.g. `FruitDao`;
158
+ - A `CompletationStage` of any `@Dao`-annotated interface, e.g. `CompletionStage<FruitDao>`.
159
+ - A `Uni` of any `@Dao`-annotated interface, e.g. `Uni<FruitDao>`.
160
+
161
+ TIP: `Uni` is a type from the Mutiny library, which is the reactive programming library used by
162
+ Quarkus. This will be explained in more detail in the "Reactive Programming" section below.
163
+
164
+ == Generating the DAO and Mapper Implementations
165
+
166
+ As you probably guessed already, we are not going to implement the interfaces above. Instead, the
167
+ Object Mapper will generate such implementations for us.
168
+
169
+ The Object Mapper is composed of 2 pieces:
170
+
171
+ 1. A (compile-time) annotation processor that scans the classpath for classes annotated with
172
+ `@Entity`, and generates code for them; and
173
+ 2. A runtime module that contains the logic to execute the generated queries.
174
+
175
+ Therefore, enabling the Object Mapper requires two steps:
176
+
177
+ 1. Declare the `cassandra-quarkus-mapper-processor` annotation processor. With Maven, this is done
178
+ by modifying the compiler plugin configuration in the project's `pom.xml` file as follows:
179
+
180
+ [source,xml]
181
+ ----
182
+ <plugin>
183
+ <artifactId>maven-compiler-plugin</artifactId>
184
+ <version>3.10.1</version>
185
+ <configuration>
186
+ <source>${java.version}</source>
187
+ <target>${java.version}</target>
188
+ <annotationProcessorPaths>
189
+ <path>
190
+ <groupId>com.datastax.oss.quarkus</groupId>
191
+ <artifactId>cassandra-quarkus-mapper-processor</artifactId>
192
+ <version>${cassandra-quarkus.version}</version>
193
+ </path>
194
+ </annotationProcessorPaths>
195
+ </configuration>
196
+ </plugin>
197
+ ----
198
+
199
+ With Gradle, this is done by adding the following line to the `build.gradle` file:
200
+
201
+ [source,groovy]
202
+ ----
203
+ annotationProcessor "com.datastax.oss.quarkus:cassandra-quarkus-mapper-processor:${cassandra-quarkus.version}"
204
+ ----
205
+
206
+ IMPORTANT: make sure you are enabling the right annotation processor! The Cassandra Quarkus
207
+ extension requires the `cassandra-quarkus-mapper-processor` annotation processor, and not the Java
208
+ driver's `java-driver-mapper-processor`. The former has more capabilities than the latter, and is
209
+ the only one suitable for use in a Quarkus application.
210
+
211
+ [start=2]
212
+ 1. Declare the `cassandra-quarkus-mapper-runtime` dependency in compile scope in the project's
213
+ `pom.xml` file as follows:
214
+
215
+ [source,xml]
216
+ ----
217
+ <dependency>
218
+ <groupId>com.datastax.oss.quarkus</groupId>
219
+ <artifactId>cassandra-quarkus-mapper-runtime</artifactId>
220
+ <version>${project.version}</version>
221
+ <scope>compile</scope>
222
+ </dependency>
223
+ ----
224
+
225
+ With Gradle, this is done by adding the following line to the `build.gradle` file:
226
+
227
+ [source,groovy]
228
+ ----
229
+ compile "com.datastax.oss.quarkus:cassandra-quarkus-mapper-runtime:${cassandra-quarkus.version}"
230
+ ----
231
+
232
+ IMPORTANT: Although this module is called "runtime", it must be declared in compile scope.
233
+
234
+ If your project is correctly set up, you should now be able to compile it without errors, and you
235
+ should see the generated code in the `target/generated-sources/annotations` directory (if you are
236
+ using Maven). You don't need to get familiar with the generated code though, as it is mostly
237
+ internal machinery to interact with the database.
238
+
149
239
== Creating a Service & JSON REST Endpoint
150
240
151
241
Now let's create a `FruitService` that will be the business layer of our application and store/load
@@ -169,19 +259,20 @@ public class FruitService {
169
259
----
170
260
171
261
Note how the service is being injected a `FruitDao` instance. This DAO instance is injected
172
- automatically.
262
+ automatically, thanks to the generated implementations .
173
263
174
264
The Cassandra Quarkus extension allows you to inject any of the following beans in your own
175
265
components:
176
266
177
267
- All `@Mapper`-annotated interfaces in your project.
178
- - All `@Dao`-annotated interfaces in your project, as long as they are produced by a corresponding
179
- `@DaoFactory`-annotated method declared in a mapper interface from your project .
268
+ - You can also inject a `CompletionStage` or `Uni` of any `@Mapper`-annotated interface.
269
+ - Any bean returned by a `@DaoFactory` method (see above for possible bean types) .
180
270
- The
181
271
link:https://javadoc.io/doc/com.datastax.oss.quarkus/cassandra-quarkus-client/latest/com/datastax/oss/quarkus/runtime/api/session/QuarkusCqlSession.html[`QuarkusCqlSession`]
182
272
bean: this application-scoped, singleton bean is your main entry point to the Cassandra client; it
183
273
is a specialized Cassandra driver session instance with a few methods tailored especially for
184
274
Quarkus. Read its javadocs carefully!
275
+ - You can also inject `CompletationStage<QuarkusCqlSession>` or `Uni<QuarkusCqlSession>`.
185
276
186
277
In our example, both `FruitMapper` and `FruitDao` could be injected anywhere. We chose to inject
187
278
`FruitDao` in `FruitService`.
@@ -375,7 +466,8 @@ docker exec -it local-cassandra-instance cqlsh
375
466
376
467
In the project root directory:
377
468
378
- - Run `mvn clean package` and then `java -jar ./target/cassandra-quarkus-quickstart-*-runner.jar` to start the application;
469
+ - Run `mvn clean package` and then `java -jar ./target/cassandra-quarkus-quickstart-*-runner.jar` to
470
+ start the application;
379
471
- Or better yet, run the application in dev mode: `mvn clean quarkus:dev`.
380
472
381
473
Now you can use curl commands to interact with the underlying REST API.
@@ -424,7 +516,7 @@ link:https://quarkus.io/guides/getting-started-reactive[Getting Started with Rea
424
516
425
517
Let's rewrite our application using reactive programming with Mutiny.
426
518
427
- First, let's to declare another DAO interface that works in a reactive way:
519
+ First, let's declare another DAO interface that works in a reactive way:
428
520
429
521
[source,java]
430
522
----
@@ -771,15 +863,17 @@ You can then point your browser to `http://localhost:8080/fruits.html` and use y
771
863
772
864
== Eager vs Lazy Initialization
773
865
774
- This extension allows you to inject either :
866
+ As explained above, this extension allows you to inject many types of beans :
775
867
776
- - a `QuarkusCqlSession` bean;
777
- - or the asynchronous version of this bean, that is, `CompletionStage<QuarkusCqlSession>`;
778
- - or the reactive version of this bean, that is, `Uni<QuarkusCqlSession>`.
868
+ - A simple bean like `QuarkusCqlSession` or `FruitDao`;
869
+ - The asynchronous version of that bean, e.g. `CompletionStage<QuarkusCqlSession>` or
870
+ `CompletionStage<FruitDao>;
871
+ - The reactive version of that bean, e.g., `Uni<QuarkusCqlSession>` or `Uni<FruitDao>`.
779
872
780
- The most straightforward approach is obviously to inject `QuarkusCqlSession` directly. This should
781
- work just fine for most applications; however, the `QuarkusCqlSession` bean needs to be initialized
782
- before it can be used, and this process is blocking.
873
+ The most straightforward approach is obviously to inject the bean directly. This should work just
874
+ fine for most applications; however, the `QuarkusCqlSession` bean, and all DAO beans that depend on
875
+ it, might take some time to initialize before they can be used for the first time, and this process
876
+ is blocking.
783
877
784
878
Fortunately, it is possible to control when the initialization should happen: the
785
879
`quarkus.cassandra.init.eager-init` parameter determines if the `QuarkusCqlSession` bean should be
0 commit comments