A sample project following Domain Driven Design with Spring Data JPA
(C) Christoph Knabe, 2017-03-17 ... 2022-01-14
In this project I am trying to apply principles of Domain Driven Design. In contrary to more complex DDD examples on the web I am applying here some simplifications. This sample application has been developed for a course on Software Engineering at Berlin University of Applied Sciences and Technology (Berliner Hochschule für Technik: BHT).
This project uses
Detailed version indications you can find in the file pom.xml.
If the correct JDK and Maven versions are installed you can simply use
mvn clean package site
This will fetch all necessary libraries, compile the project, collect the exception message texts,
execute the test suite, package all into an executable .jar file, and generate the reports and project site.
The most interesting report is about Code Coverage.
If you experience problems due to versioning of JDK and Maven, see the chapter about it in document Maven and IDE Integration.
After this is working you can import the Maven project into your Java IDE (Spring Tools may be preferred, see the chapter about IDE Integration in Maven and IDE Integration)
You can run the application (a REST server) in your IDE by running class de.beuth.knabe.spring_ddd_bank.Application as Java Application or on the command line after
mvn package
by
java -jar target/spring-ddd-bank-0.1-SNAPSHOT.jar
This will start the web server Tomcat with the web application Spring DDD Bank. The latter runs the database Derby in embedded mode for the web application, but also offers network access to the database. In the last lines of the log you will see messages like the following:\
Tomcat started on port(s): 8080 (http)
\
Apache Derby Network Server 10.12.1.1 - (1704137) has been started and is ready to accept connections on port 1527.
\
In these messages you can see the port of the web server (8080), and of the Derby database (1527).
You can shutdown it by typing <Ctrl/C>. Killing it in IntelliJ IDEA or Spring Tools by the red icon also stopped it without a visible negative effect.
Modeling the domain layer as one package, which does not depend on any other package besides standard Java SE packages as java.time
and javax.persistence
. The latter only for the JPA annotations.
Prefer a Rich Domain Model over an Anemic Domain Model by having relevant business logic methods in entity class Client.
This required Domain Object Dependency Injection (DODI), but is now done manually by method Client.provideWith
. (The former automatic DODI on Java 8 by AspectJ compile-time weaving was abandoned, as there were serious configuration issues with AspectJ on Java 11. AspectJ seems to become less popular.)
The Domain Layer references required services only by self-defined, minimal interfaces (in package domain.imports).
Implementing required services in the infrastructure layer (in package infrastructure).
Linking together required services and their implementations by Spring Dependency Injection.
Implementing an interface layer for external access to the application. This is implemented as a REST service in package rest_interface.
.uxf
.@Transactional
to class ApplicationController.In the file MessageText.properties
. The editable original with some fixed message texts is in src/main/resources/.
By Maven phase compile
this file is copied to target/classes/
.
During the following phase process-classes
the exception message texts are extracted from the JavaDoc comments of all exceptions under src/main/java/
by the ExceptionMessagesDoclet
as configured for the maven-javadoc-plugin
. They are appended to the message text file in target/classes/
.
This process is excluded from m2e lifecycle mapping in the pom.xml
.
client.id
and account.id
as a composite ID for AccountAccess
.
Not so easy, see JPA: How to associate entities with relationship attributes?