Using JHipster JDL to Define Entities and Generate Full-Stack Code
Learn how to write a JHipster JDL file to define entities and relationships, then generate the full Spring Boot backend and Angular/React frontend with one command.
01 Sept 2025, 12:33 UTC

The problem: repetitive boilerplate for every new feature
When you start a new module in a JHipster project, you typically create JPA entities, Spring Data repositories, service classes, REST controllers, and then the matching Angular or React components. Doing this by hand for each entity is slow, error-prone, and makes it hard to keep the backend and frontend in sync as the model evolves.
The thesis
JHipster Domain Language (JDL) lets you describe entities, relationships, and generation options in a single declarative text file. One command, jhipster import-jdl, then produces the complete stack: database changelogs, Java backend code, and client-side components.
How JDL works
JDL is a plain-text language written in a .jdl file. Each entity block declares fields with types and validation rules such as required, minlength, and maxlength. Relationships are declared with keywords like OneToMany or ManyToMany. Generation options such as dto, service, pagination, filter, and clientRootFolder are written directly in the file, so you control the produced code without touching generator templates.
Be aware that the parser is strict: a missing comma or misplaced keyword aborts the import with an error pointing at the offending line. Keep the file small at first and grow it incrementally.
Worked example: an Author-Book OneToMany model
The steps below assume a JHipster monolith generated with version 7.9.x (confirm with jhipster --version; option names such as serviceImpl depend on the JHipster release, so check release notes if you are on a different version).
- Create a file
author-book.jdlin the project root:
entity Author {
name String required minlength(2)
birthDate Instant
}
entity Book {
title String required maxlength(100)
publishedDate Instant
price BigDecimal required min(0)
}
relationship OneToMany {
Author{books} to Book{author}
}
dto Author, Book with mapstruct
service Author, Book with serviceImpl
paginate Author, Book with pagination
filter Author, Book- From the project root, run the import (no special permissions needed beyond write access to the project):
jhipster import-jdl author-book.jdlThis generates JPA entities, Spring Data repositories, AuthorServiceImpl and BookServiceImpl, REST resources, MapStruct DTO mappers, Liquibase changelogs for both tables, and the matching Angular or React models, services, and CRUD components.
- Build and start the application:
./mvnw verify
./mvnwUse ./gradlew build and ./gradlew for a Gradle project. Once running, check http://localhost:8080/api/authors and http://localhost:8080/api/books; both should return HTTP 200 with JSON arrays (you will need to log in first, since security is enabled by default). In the UI, the entity menu should let you create, edit, and delete authors and books, with the relationship shown as a dropdown on the Book form.
- Optionally validate the database changelog:
./mvnw liquibase:updateIf this applies cleanly, the schema matches the JDL definitions.
Trade-offs and limitations
JDL covers the common generation options well, but it is not a complete modeling language. Custom JPQL queries, non-standard DTO mappings, and inheritance or polymorphic associations cannot be expressed directly; you add those with manual JPA annotations or template overrides after generation. Also, older JDL files may use options deprecated in newer JHipster releases, so review release notes before regenerating after an upgrade.
Actionable closing
If you already have a JHipster project, run jhipster export-jdl to extract your current model into a JDL file, commit it to version control, and treat it as the single source of truth for your data model. From there, iterate: add an option like dto mapstruct, re-run import-jdl, and verify the endpoints respond as expected before moving on.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.