{"id":1941,"date":"2024-06-19T16:52:25","date_gmt":"2024-06-19T16:52:25","guid":{"rendered":"https:\/\/www.w3computing.com\/articles\/?p=1941"},"modified":"2024-06-19T17:51:50","modified_gmt":"2024-06-19T17:51:50","slug":"how-to-implement-cqrs-command-query-responsibility-segregation-in-java","status":"publish","type":"post","link":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/","title":{"rendered":"How to Implement CQRS (Command Query Responsibility Segregation) in Java"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Command Query Responsibility Segregation (CQRS) is a design pattern that separates the read and write operations of a data store. The main idea is to use different models to update data (command) and read data (query). This separation can provide several benefits, such as improved performance, scalability, and security. In this tutorial, we will explore how to implement CQRS in a Java application.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Understanding CQRS<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is CQRS?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">CQRS stands for Command Query Responsibility Segregation. It&#8217;s a pattern that separates the responsibility of reading and writing data. In traditional CRUD (Create, Read, Update, Delete) applications, the same model is used for both reads and writes. CQRS, on the other hand, uses distinct models for commands (writes) and queries (reads).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Benefits of CQRS<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Scalability<\/strong>: By separating reads and writes, each can be scaled independently.<\/li>\n\n\n\n<li><strong>Performance<\/strong>: Optimized read models can be designed to improve query performance.<\/li>\n\n\n\n<li><strong>Security<\/strong>: Different models allow for fine-grained security policies.<\/li>\n\n\n\n<li><strong>Maintainability<\/strong>: Simplifies the system by separating concerns.<\/li>\n\n\n\n<li><strong>Event Sourcing<\/strong>: Often used with CQRS, providing an audit log of all changes.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">CQRS vs. CRUD<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>CRUD<\/strong>: Single model for both reading and writing. Simpler, but can become complex and less performant as the application grows.<\/li>\n\n\n\n<li><strong>CQRS<\/strong>: Separate models for commands and queries. More complex initially but offers better scalability and performance.<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">2. Setting Up the Project<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Project Structure<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We&#8217;ll create a Maven project with the following structure:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"Bash\" data-shcb-language-slug=\"bash\"><span><code class=\"hljs language-bash\">cqrs-demo\n\u251c\u2500\u2500 src\n\u2502   \u251c\u2500\u2500 main\n\u2502   \u2502   \u251c\u2500\u2500 java\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 com\n\u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 example\n\u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 <span class=\"hljs-built_in\">command<\/span>\n\u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 query\n\u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 event\n\u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 model\n\u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 service\n\u2502   \u2502   \u2502   \u2502   \u2502   \u251c\u2500\u2500 bus\n\u2502   \u2502   \u2502   \u251c\u2500\u2500 resources\n\u2502   \u251c\u2500\u2500 <span class=\"hljs-built_in\">test<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Bash<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">bash<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Dependencies<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Add the following dependencies to your <code>pom.xml<\/code> file:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\"><span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.springframework.boot<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>spring-boot-starter<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.springframework.boot<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>spring-boot-starter-data-jpa<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.springframework.boot<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>spring-boot-starter-web<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>org.springframework.boot<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>spring-boot-starter-test<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">scope<\/span>&gt;<\/span>test<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">scope<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>com.h2database<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">groupId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>h2<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">artifactId<\/span>&gt;<\/span>\n        <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">scope<\/span>&gt;<\/span>runtime<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">scope<\/span>&gt;<\/span>\n    <span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependency<\/span>&gt;<\/span>\n<span class=\"hljs-tag\">&lt;\/<span class=\"hljs-name\">dependencies<\/span>&gt;<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">3. Implementing the Write Model (Commands)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Command Model<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Commands represent actions that change the state of the system. Each command should be immutable and only contain the data needed for the operation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a command for creating a new user:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.command;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CreateUserCommand<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String userId;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String username;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String email;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">CreateUserCommand<\/span><span class=\"hljs-params\">(String userId, String username, String email)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userId = userId;\n        <span class=\"hljs-keyword\">this<\/span>.username = username;\n        <span class=\"hljs-keyword\">this<\/span>.email = email;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> String <span class=\"hljs-title\">getUserId<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> userId;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> String <span class=\"hljs-title\">getUsername<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> username;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> String <span class=\"hljs-title\">getEmail<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> email;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Command Handler<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The command handler processes the commands. It should contain the business logic for handling each command.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.command;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> com.example.service.UserService;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Service;\n\n<span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CreateUserCommandHandler<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> UserService userService;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">CreateUserCommandHandler<\/span><span class=\"hljs-params\">(UserService userService)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userService = userService;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">handle<\/span><span class=\"hljs-params\">(CreateUserCommand command)<\/span> <\/span>{\n        User user = <span class=\"hljs-keyword\">new<\/span> User(command.getUserId(), command.getUsername(), command.getEmail());\n        userService.save(user);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Command Bus<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The command bus is responsible for dispatching commands to their respective handlers.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.bus;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.command.CreateUserCommand;\n<span class=\"hljs-keyword\">import<\/span> com.example.command.CreateUserCommandHandler;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Component;\n\n<span class=\"hljs-meta\">@Component<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CommandBus<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> CreateUserCommandHandler createUserCommandHandler;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">CommandBus<\/span><span class=\"hljs-params\">(CreateUserCommandHandler createUserCommandHandler)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.createUserCommandHandler = createUserCommandHandler;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">dispatch<\/span><span class=\"hljs-params\">(CreateUserCommand command)<\/span> <\/span>{\n        createUserCommandHandler.handle(command);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">4. Implementing the Read Model (Queries)<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Query Model<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Queries represent requests for data. Like commands, queries should be immutable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create a query to fetch user details:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.query;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">GetUserQuery<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String userId;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">GetUserQuery<\/span><span class=\"hljs-params\">(String userId)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userId = userId;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> String <span class=\"hljs-title\">getUserId<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> userId;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Query Handler<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The query handler processes the queries and returns the required data.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.query;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> com.example.service.UserService;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Service;\n\n<span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">GetUserQueryHandler<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> UserService userService;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">GetUserQueryHandler<\/span><span class=\"hljs-params\">(UserService userService)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userService = userService;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> User <span class=\"hljs-title\">handle<\/span><span class=\"hljs-params\">(GetUserQuery query)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> userService.findById(query.getUserId());\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Query Bus<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The query bus is responsible for dispatching queries to their respective handlers.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.bus;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.query.GetUserQuery;\n<span class=\"hljs-keyword\">import<\/span> com.example.query.GetUserQueryHandler;\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Component;\n\n<span class=\"hljs-meta\">@Component<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">QueryBus<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> GetUserQueryHandler getUserQueryHandler;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">QueryBus<\/span><span class=\"hljs-params\">(GetUserQueryHandler getUserQueryHandler)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.getUserQueryHandler = getUserQueryHandler;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> User <span class=\"hljs-title\">dispatch<\/span><span class=\"hljs-params\">(GetUserQuery query)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> getUserQueryHandler.handle(query);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">5. Integrating with Event Sourcing<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What is Event Sourcing?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Event Sourcing is a pattern where state changes are stored as a sequence of events. Instead of storing the current state, you store the events that lead to the current state. This provides a complete audit log and can be useful for reconstructing past states.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Implementing Event Sourcing<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To integrate event sourcing, we need to define events and an event store.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Event Model<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Create an event for user creation:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.event;\n\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserCreatedEvent<\/span> <\/span>{\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String userId;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String username;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> String email;\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">UserCreatedEvent<\/span><span class=\"hljs-params\">(String userId, String username, String email)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userId = userId;\n        <span class=\"hljs-keyword\">this<\/span>.username = username;\n        <span class=\"hljs-keyword\">this<\/span>.email = email;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> String <span class=\"hljs-title\">getUserId<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> userId;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> String <span class=\"hljs-title\">getUsername<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> username;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> String <span class=\"hljs-title\">getEmail<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> email;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Event Store<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">The event store saves events and can replay them to reconstruct the state.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.event;\n\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Service;\n\n<span class=\"hljs-keyword\">import<\/span> java.util.ArrayList;\n<span class=\"hljs-keyword\">import<\/span> java.util.List;\n\n<span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">EventStore<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> List&lt;UserCreatedEvent&gt; events = <span class=\"hljs-keyword\">new<\/span> ArrayList&lt;&gt;();\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">saveEvent<\/span><span class=\"hljs-params\">(UserCreatedEvent event)<\/span> <\/span>{\n        events.add(event);\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> List&lt;UserCreatedEvent&gt; <span class=\"hljs-title\">getEvents<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> events;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Modifying Command Handler<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\">Modify the <code>CreateUserCommandHandler<\/code> to save events:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.command;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.event.EventStore\n\n;\n<span class=\"hljs-keyword\">import<\/span> com.example.event.UserCreatedEvent;\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> com.example.service.UserService;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Service;\n\n<span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CreateUserCommandHandler<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> UserService userService;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> EventStore eventStore;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">CreateUserCommandHandler<\/span><span class=\"hljs-params\">(UserService userService, EventStore eventStore)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userService = userService;\n        <span class=\"hljs-keyword\">this<\/span>.eventStore = eventStore;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">handle<\/span><span class=\"hljs-params\">(CreateUserCommand command)<\/span> <\/span>{\n        User user = <span class=\"hljs-keyword\">new<\/span> User(command.getUserId(), command.getUsername(), command.getEmail());\n        userService.save(user);\n\n        UserCreatedEvent event = <span class=\"hljs-keyword\">new<\/span> UserCreatedEvent(command.getUserId(), command.getUsername(), command.getEmail());\n        eventStore.saveEvent(event);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">6. Handling Concurrency<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Concurrency can be a challenge in CQRS systems, especially when multiple commands are trying to modify the same data. There are two main strategies for handling concurrency: optimistic and pessimistic concurrency control.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Optimistic Concurrency Control<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In optimistic concurrency control, you assume that conflicts are rare and only check for conflicts before committing the transaction.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Add a version field to the user entity:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.model;\n\n<span class=\"hljs-keyword\">import<\/span> javax.persistence.Entity;\n<span class=\"hljs-keyword\">import<\/span> javax.persistence.Id;\n<span class=\"hljs-keyword\">import<\/span> javax.persistence.Version;\n\n<span class=\"hljs-meta\">@Entity<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">User<\/span> <\/span>{\n\n    <span class=\"hljs-meta\">@Id<\/span>\n    <span class=\"hljs-keyword\">private<\/span> String userId;\n    <span class=\"hljs-keyword\">private<\/span> String username;\n    <span class=\"hljs-keyword\">private<\/span> String email;\n\n    <span class=\"hljs-meta\">@Version<\/span>\n    <span class=\"hljs-keyword\">private<\/span> Long version;\n\n    <span class=\"hljs-comment\">\/\/ Constructors, getters, and setters omitted for brevity<\/span>\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Modify the user service to handle version conflicts:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.service;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> com.example.repository.UserRepository;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.dao.OptimisticLockingFailureException;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Service;\n\n<span class=\"hljs-keyword\">import<\/span> java.util.Optional;\n\n<span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserService<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> UserRepository userRepository;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">UserService<\/span><span class=\"hljs-params\">(UserRepository userRepository)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userRepository = userRepository;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">save<\/span><span class=\"hljs-params\">(User user)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">try<\/span> {\n            userRepository.save(user);\n        } <span class=\"hljs-keyword\">catch<\/span> (OptimisticLockingFailureException e) {\n            <span class=\"hljs-comment\">\/\/ Handle version conflict<\/span>\n        }\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> User <span class=\"hljs-title\">findById<\/span><span class=\"hljs-params\">(String userId)<\/span> <\/span>{\n        Optional&lt;User&gt; user = userRepository.findById(userId);\n        <span class=\"hljs-keyword\">return<\/span> user.orElse(<span class=\"hljs-keyword\">null<\/span>);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Pessimistic Concurrency Control<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">In pessimistic concurrency control, you lock the data when a transaction starts and release the lock when the transaction ends.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Modify the user service to use pessimistic locking:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.service;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> com.example.repository.UserRepository;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.stereotype.Service;\n\n<span class=\"hljs-keyword\">import<\/span> javax.persistence.EntityManager;\n<span class=\"hljs-keyword\">import<\/span> javax.persistence.LockModeType;\n\n<span class=\"hljs-meta\">@Service<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserService<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> UserRepository userRepository;\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> EntityManager entityManager;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">UserService<\/span><span class=\"hljs-params\">(UserRepository userRepository, EntityManager entityManager)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.userRepository = userRepository;\n        <span class=\"hljs-keyword\">this<\/span>.entityManager = entityManager;\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">save<\/span><span class=\"hljs-params\">(User user)<\/span> <\/span>{\n        entityManager.lock(user, LockModeType.PESSIMISTIC_WRITE);\n        userRepository.save(user);\n    }\n\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> User <span class=\"hljs-title\">findById<\/span><span class=\"hljs-params\">(String userId)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> entityManager.find(User<span class=\"hljs-class\">.<span class=\"hljs-keyword\">class<\/span>, <span class=\"hljs-title\">userId<\/span>, <span class=\"hljs-title\">LockModeType<\/span>.<span class=\"hljs-title\">PESSIMISTIC_READ<\/span>)<\/span>;\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">7. Putting It All Together<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Example Use Case<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s put everything together with an example use case of creating and querying a user.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Create a User Controller<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.controller;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.bus.CommandBus;\n<span class=\"hljs-keyword\">import<\/span> com.example.command.CreateUserCommand;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.web.bind.annotation.*;\n\n<span class=\"hljs-meta\">@RestController<\/span>\n<span class=\"hljs-meta\">@RequestMapping<\/span>(<span class=\"hljs-string\">\"\/users\"<\/span>)\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserController<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> CommandBus commandBus;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">UserController<\/span><span class=\"hljs-params\">(CommandBus commandBus)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.commandBus = commandBus;\n    }\n\n    <span class=\"hljs-meta\">@PostMapping<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">createUser<\/span><span class=\"hljs-params\">(@RequestBody CreateUserCommand command)<\/span> <\/span>{\n        commandBus.dispatch(command);\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Query a User Controller<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example.controller;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.bus.QueryBus;\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> com.example.query.GetUserQuery;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.web.bind.annotation.*;\n\n<span class=\"hljs-meta\">@RestController<\/span>\n<span class=\"hljs-meta\">@RequestMapping<\/span>(<span class=\"hljs-string\">\"\/users\"<\/span>)\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">UserQueryController<\/span> <\/span>{\n\n    <span class=\"hljs-keyword\">private<\/span> <span class=\"hljs-keyword\">final<\/span> QueryBus queryBus;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-title\">UserQueryController<\/span><span class=\"hljs-params\">(QueryBus queryBus)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">this<\/span>.queryBus = queryBus;\n    }\n\n    <span class=\"hljs-meta\">@GetMapping<\/span>(<span class=\"hljs-string\">\"\/{userId}\"<\/span>)\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> User <span class=\"hljs-title\">getUser<\/span><span class=\"hljs-params\">(@PathVariable String userId)<\/span> <\/span>{\n        <span class=\"hljs-keyword\">return<\/span> queryBus.dispatch(<span class=\"hljs-keyword\">new<\/span> GetUserQuery(userId));\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Testing the Implementation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Write integration tests to verify the implementation.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Test Creating a User<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.command.CreateUserCommand;\n<span class=\"hljs-keyword\">import<\/span> com.example.event.EventStore;\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> com.example.repository.UserRepository;\n<span class=\"hljs-keyword\">import<\/span> org.junit.jupiter.api.Test;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.boot.test.context.SpringBootTest;\n\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-keyword\">static<\/span> org.junit.jupiter.api.Assertions.assertEquals;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-keyword\">static<\/span> org.junit.jupiter.api.Assertions.assertNotNull;\n\n<span class=\"hljs-meta\">@SpringBootTest<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">CreateUserCommandTest<\/span> <\/span>{\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-keyword\">private<\/span> UserRepository userRepository;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-keyword\">private<\/span> EventStore eventStore;\n\n    <span class=\"hljs-meta\">@Test<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">testCreateUser<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        CreateUserCommand command = <span class=\"hljs-keyword\">new<\/span> CreateUserCommand(<span class=\"hljs-string\">\"1\"<\/span>, <span class=\"hljs-string\">\"john_doe\"<\/span>, <span class=\"hljs-string\">\"john@example.com\"<\/span>);\n        commandBus.dispatch(command);\n\n        User user = userRepository.findById(<span class=\"hljs-string\">\"1\"<\/span>).orElse(<span class=\"hljs-keyword\">null<\/span>);\n        assertNotNull(user);\n        assertEquals(<span class=\"hljs-string\">\"john_doe\"<\/span>, user.getUsername());\n        assertEquals(<span class=\"hljs-string\">\"john@example.com\"<\/span>, user.getEmail());\n\n        UserCreatedEvent event = eventStore.getEvents().get(<span class=\"hljs-number\">0<\/span>);\n        assertEquals(<span class=\"hljs-string\">\"1\"<\/span>, event.getUserId());\n        assertEquals(<span class=\"hljs-string\">\"john_doe\"<\/span>, event.getUsername());\n        assertEquals(<span class=\"hljs-string\">\"john@example.com\"<\/span>, event.getEmail());\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h4 class=\"wp-block-heading\">Test Querying a User<\/h4>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"Java\" data-shcb-language-slug=\"java\"><span><code class=\"hljs language-java\"><span class=\"hljs-keyword\">package<\/span> com.example;\n\n<span class=\"hljs-keyword\">import<\/span> com.example.model.User;\n<span class=\"hljs-keyword\">import<\/span> com.example.repository.UserRepository;\n<span class=\"hljs-keyword\">import<\/span> com.example.query.GetUserQuery;\n<span class=\"hljs-keyword\">import<\/span> org.junit.jupiter.api.Test;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.beans.factory.annotation.Autowired;\n<span class=\"hljs-keyword\">import<\/span> org.springframework.boot.test.context.SpringBootTest;\n\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-keyword\">static<\/span> org.junit.jupiter.api.Assertions.assertEquals;\n<span class=\"hljs-keyword\">import<\/span> <span class=\"hljs-keyword\">static<\/span> org.junit.jupiter.api.Assertions.assertNotNull;\n\n<span class=\"hljs-meta\">@SpringBootTest<\/span>\n<span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-class\"><span class=\"hljs-keyword\">class<\/span> <span class=\"hljs-title\">GetUserQueryTest<\/span> <\/span>{\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-keyword\">private<\/span> UserRepository userRepository;\n\n    <span class=\"hljs-meta\">@Autowired<\/span>\n    <span class=\"hljs-keyword\">private<\/span> QueryBus queryBus;\n\n    <span class=\"hljs-meta\">@Test<\/span>\n    <span class=\"hljs-function\"><span class=\"hljs-keyword\">public<\/span> <span class=\"hljs-keyword\">void<\/span> <span class=\"hljs-title\">testGetUser<\/span><span class=\"hljs-params\">()<\/span> <\/span>{\n        User user = <span class=\"hljs-keyword\">new<\/span> User(<span class=\"hljs-string\">\"1\"<\/span>, <span class=\"hljs-string\">\"john_doe\"<\/span>, <span class=\"hljs-string\">\"john@example.com\"<\/span>);\n        userRepository.save(user);\n\n        User result = queryBus.dispatch(<span class=\"hljs-keyword\">new<\/span> GetUserQuery(<span class=\"hljs-string\">\"1\"<\/span>));\n        assertNotNull(result);\n        assertEquals(<span class=\"hljs-string\">\"john_doe\"<\/span>, result.getUsername());\n        assertEquals(<span class=\"hljs-string\">\"john@example.com\"<\/span>, result.getEmail());\n    }\n}<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">Java<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">java<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h2 class=\"wp-block-heading\">8. Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Implementing CQRS in Java involves creating separate models and handlers for commands and queries, integrating with event sourcing for better state management, and handling concurrency to ensure data consistency. This tutorial provided a step-by-step guide to implementing CQRS in a Java application, highlighting the benefits and challenges of this design pattern.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">By following these steps, you can build scalable, maintainable, and performant applications that leverage the power of CQRS. Remember that while CQRS offers many advantages, it also introduces complexity, so it&#8217;s essential to evaluate whether it fits your specific use case before adopting it.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Command Query Responsibility Segregation (CQRS) is a design pattern that separates the read and write operations of a data store. The main idea is to use different models to update data (command) and read data (query). This separation can provide several benefits, such as improved performance, scalability, and security. In this tutorial, we will [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_genesis_hide_title":false,"_genesis_hide_breadcrumbs":false,"_genesis_hide_singular_image":false,"_genesis_hide_footer_widgets":false,"_genesis_custom_body_class":"","_genesis_custom_post_class":"","_genesis_layout":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_post_was_ever_published":false},"categories":[5,4],"tags":[],"class_list":["post-1941","post","type-post","status-publish","format-standard","category-java","category-programming-languages","entry"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Implement CQRS (Command Query Responsibility Segregation) in Java<\/title>\n<meta name=\"description\" content=\"Command Query Responsibility Segregation (CQRS) is a design pattern that separates the read and write operations of a data store.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Implement CQRS (Command Query Responsibility Segregation) in Java\" \/>\n<meta property=\"og:description\" content=\"Command Query Responsibility Segregation (CQRS) is a design pattern that separates the read and write operations of a data store.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/\" \/>\n<meta property=\"article:published_time\" content=\"2024-06-19T16:52:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-06-19T17:51:50+00:00\" \/>\n<meta name=\"author\" content=\"w3compadmin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"w3compadmin\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"TechArticle\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\\\/\"},\"author\":{\"name\":\"w3compadmin\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"headline\":\"How to Implement CQRS (Command Query Responsibility Segregation) in Java\",\"datePublished\":\"2024-06-19T16:52:25+00:00\",\"dateModified\":\"2024-06-19T17:51:50+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\\\/\"},\"wordCount\":719,\"articleSection\":[\"Java\",\"Programming Languages\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\\\/\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\\\/\",\"name\":\"How to Implement CQRS (Command Query Responsibility Segregation) in Java\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\"},\"datePublished\":\"2024-06-19T16:52:25+00:00\",\"dateModified\":\"2024-06-19T17:51:50+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\"},\"description\":\"Command Query Responsibility Segregation (CQRS) is a design pattern that separates the read and write operations of a data store.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\\\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Articles Home\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Programming Languages\",\"item\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/programming-languages\\\/\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"How to Implement CQRS (Command Query Responsibility Segregation) in Java\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#website\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/\",\"name\":\"Developer Articles Hub\",\"description\":\"\",\"alternateName\":\"Developer Articles\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/#\\\/schema\\\/person\\\/a550b3e20d78bb4f79b7c6b7b53f0561\",\"name\":\"w3compadmin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"url\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"contentUrl\":\"https:\\\/\\\/www.w3computing.com\\\/articles\\\/wp-content\\\/litespeed\\\/avatar\\\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167\",\"caption\":\"w3compadmin\"},\"sameAs\":[\"http:\\\/\\\/w3computing.com\\\/articles\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Implement CQRS (Command Query Responsibility Segregation) in Java","description":"Command Query Responsibility Segregation (CQRS) is a design pattern that separates the read and write operations of a data store.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/","og_locale":"en_US","og_type":"article","og_title":"How to Implement CQRS (Command Query Responsibility Segregation) in Java","og_description":"Command Query Responsibility Segregation (CQRS) is a design pattern that separates the read and write operations of a data store.","og_url":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/","article_published_time":"2024-06-19T16:52:25+00:00","article_modified_time":"2024-06-19T17:51:50+00:00","author":"w3compadmin","twitter_card":"summary_large_image","twitter_misc":{"Written by":"w3compadmin","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"TechArticle","@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/#article","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/"},"author":{"name":"w3compadmin","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"headline":"How to Implement CQRS (Command Query Responsibility Segregation) in Java","datePublished":"2024-06-19T16:52:25+00:00","dateModified":"2024-06-19T17:51:50+00:00","mainEntityOfPage":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/"},"wordCount":719,"articleSection":["Java","Programming Languages"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/","url":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/","name":"How to Implement CQRS (Command Query Responsibility Segregation) in Java","isPartOf":{"@id":"https:\/\/www.w3computing.com\/articles\/#website"},"datePublished":"2024-06-19T16:52:25+00:00","dateModified":"2024-06-19T17:51:50+00:00","author":{"@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561"},"description":"Command Query Responsibility Segregation (CQRS) is a design pattern that separates the read and write operations of a data store.","breadcrumb":{"@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.w3computing.com\/articles\/how-to-implement-cqrs-command-query-responsibility-segregation-in-java\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Articles Home","item":"https:\/\/www.w3computing.com\/articles\/"},{"@type":"ListItem","position":2,"name":"Programming Languages","item":"https:\/\/www.w3computing.com\/articles\/programming-languages\/"},{"@type":"ListItem","position":3,"name":"How to Implement CQRS (Command Query Responsibility Segregation) in Java"}]},{"@type":"WebSite","@id":"https:\/\/www.w3computing.com\/articles\/#website","url":"https:\/\/www.w3computing.com\/articles\/","name":"Developer Articles Hub","description":"","alternateName":"Developer Articles","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.w3computing.com\/articles\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.w3computing.com\/articles\/#\/schema\/person\/a550b3e20d78bb4f79b7c6b7b53f0561","name":"w3compadmin","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","url":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","contentUrl":"https:\/\/www.w3computing.com\/articles\/wp-content\/litespeed\/avatar\/bd481d404e42caa2763662a3bfe825f8.jpg?ver=1781352167","caption":"w3compadmin"},"sameAs":["http:\/\/w3computing.com\/articles"]}]}},"featured_image_src":null,"featured_image_src_square":null,"author_info":{"display_name":"w3compadmin","author_link":"https:\/\/www.w3computing.com\/articles\/author\/w3compadmin\/"},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1941","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/comments?post=1941"}],"version-history":[{"count":3,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1941\/revisions"}],"predecessor-version":[{"id":1944,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/posts\/1941\/revisions\/1944"}],"wp:attachment":[{"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/media?parent=1941"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/categories?post=1941"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.w3computing.com\/articles\/wp-json\/wp\/v2\/tags?post=1941"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}