This demo shows how Debezium can be used to invalidate items in the JPA 2nd level cache after external data changes, e.g. a manual record update in the database, bypassing the application layer.
The application uses Quarkus, Hibernate, and PostgreSQL as a database.
The domain model is centered around purchase orders of given items.
The Item
entity is marked as cacheable, i.e. after updates to an item (e.g. its base price),
it must be purged from the 2nd-level cache in order to correctly calculate the price of future orders of that item.
-
First start the database container.
mvn docker:start
This will start the
quay.io/debezium/example-postgres:latest
container that will be used to store our JPA entities and the database that the Debezium will capture changes from, too. -
Run the application using the Quarkus development mode.
mvn clean quarkus:dev
The application will start in the development mode and run until you press
Ctrl+C
to stop the application. -
Place an order for item 1003 using curl:
curl -H "Content-Type: application/json" \ -X POST \ --data @resources/data/create-order-request.json \ http://localhost:8080/rest/orders
Or, if httpie is your preferred CLI HTTP client:
cat resources/data/create-order-request.json | http POST http://localhost:8080/rest/orders
-
Update the price of item 10003 directly in the database:
docker exec postgres-server-test-database-1 bash -c 'psql -U $POSTGRES_USER $POSTGRES_DB -c "UPDATE item SET price = 20.99 where id = 10003"'
-
Now use the REST endpoint to verify that the item has been purged from the cache:
curl -H "Content-Type: application/json" \ -X GET \ http://localhost:8080/rest/cache/item/10003
or via httpie:
http GET http://localhost:8080/rest/cache/item/10003
-
Place another order of that item and observe how the calculated total price reflects the change applied above. Also observe the application's log how the
item
table is queried. -
Now, update the item again using the application's REST endpoint this time:
curl -H "Content-Type: application/json" \ -X PUT \ --data @resources/data/update-item-request.json \ http://localhost:8080/rest/items/10003
or via httpie:
cat resources/data/update-item-request.json | http PUT http://localhost:8080/rest/items/10003
-
The Debezium CDC event handler detects this transaction is issued by the application, which results in the item not being removed from the cache: You can test this use case using curl:
curl -H "Content-Type: application/json" \ -X GET \ http://localhost:8080/rest/cache/item/10003
or using httpie:
http GET http://localhost:8080/rest/cache/item/10003
-
If you place another order, the
Item
entity is obtained from the cache, avoiding the database round-trip. -
Press
Ctrl+C
in the terminal to stop the Quarkus running application. -
Execute
mvn docker:stop
, to stop the PostgreSQL database container.
-
First start the PostgreSQL database container using maven:
mvn docker:start
-
Next start the application in Quarkus development mode:
mvn clean quarkus:dev
To obtain a database session in PostgreSQL, run:
docker run -it --rm --link postgres-1:postgres quay.io/debezium/example-postgres:latest psql -h postgres -U postgresuser --dbname inventory
- Stop the Quarkus application by pressing
Ctrl+C
in the terminal. - Execute
mvn docker:stop
to stop the PostgreSQL database container.