{"id":18258744,"url":"https://github.com/manoelcampos/dtogen","last_synced_at":"2025-07-09T15:39:48.090Z","repository":{"id":218631073,"uuid":"746261996","full_name":"manoelcampos/dtogen","owner":"manoelcampos","description":"A Java 21+ annotation-based, validation-aware DTO generation library following DRY and avoiding boilerplate code.","archived":false,"fork":false,"pushed_at":"2025-02-27T01:31:23.000Z","size":236,"stargazers_count":3,"open_issues_count":7,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-05T12:04:00.968Z","etag":null,"topics":["annotation","annotation-processing","annotation-processor","dto","dto-mapper","dtogen","java21","jdk21"],"latest_commit_sha":null,"homepage":"https://manoelcampos.github.io/dtogen","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/manoelcampos.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-01-21T14:56:47.000Z","updated_at":"2025-02-27T01:31:06.000Z","dependencies_parsed_at":null,"dependency_job_id":"68337310-2273-4b73-900d-e472bad3bf49","html_url":"https://github.com/manoelcampos/dtogen","commit_stats":null,"previous_names":["manoelcampos/dtogen"],"tags_count":15,"template":false,"template_full_name":null,"purl":"pkg:github/manoelcampos/dtogen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manoelcampos%2Fdtogen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manoelcampos%2Fdtogen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manoelcampos%2Fdtogen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manoelcampos%2Fdtogen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/manoelcampos","download_url":"https://codeload.github.com/manoelcampos/dtogen/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/manoelcampos%2Fdtogen/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264486998,"owners_count":23616179,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["annotation","annotation-processing","annotation-processor","dto","dto-mapper","dtogen","java21","jdk21"],"created_at":"2024-11-05T10:34:16.222Z","updated_at":"2025-07-09T15:39:48.029Z","avatar_url":"https://github.com/manoelcampos.png","language":"Java","funding_links":[],"categories":["Bean映射\u0026复制"],"sub_categories":[],"readme":"# Java automatic DTO Generation Library [![Build Status](https://github.com/manoelcampos/dtogen/actions/workflows/build.yml/badge.svg)](https://github.com/manoelcampos/dtogen/actions/workflows/build.yml) [![Maven Central](https://img.shields.io/maven-central/v/io.github.manoelcampos/dtogen.svg?label=Maven%20Central)](https://central.sonatype.com/search?q=dtogen\u0026namespace=io.github.manoelcampos) [![javadoc](https://javadoc.io/badge2/io.github.manoelcampos/dtogen/javadoc.svg)](https://javadoc.io/doc/io.github.manoelcampos/dtogen) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/dfcc539bb75247fab44f29fbefbc4b4a)](https://app.codacy.com/gh/manoelcampos/dtogen/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_grade) [![Codacy Badge](https://app.codacy.com/project/badge/Coverage/dfcc539bb75247fab44f29fbefbc4b4a)](https://app.codacy.com/gh/manoelcampos/dtogen/dashboard?utm_source=gh\u0026utm_medium=referral\u0026utm_content=\u0026utm_campaign=Badge_coverage)\n\nDTOGen is a Java 21+ library that automatically generates [Data Transfer Object](https://en.wikipedia.org/wiki/Data_transfer_object) (DTO) [records](https://openjdk.org/jeps/395) from a given model class/record using annotations. \nIt is a straightforward library that requires no extra configuration to work: just add the dependency and include the `@DTO` annotation on desired model classes to see the magic of generating DTO records happening. \n\nThe library is type-safe and validation-aware. It means that if you use [Lombok](http://projectlombok.org), [Hibernate Validator](https://hibernate.org/validator/) Annotations or other ones, they will be copied to the DTO fields. This way, validation will be performed on the DTO fields as well, so that you don't need to duplicate validation rules between the model class and the DTO. \n\nAdditionally, all the JavaDocs from fields in the model classes/records are copied to the generated DTO records. This way, you can have a complete documentation for the DTOs as well.\n\nIt relies on Annotation Processing to automatically create Java files containing the DTOs. Since it generates DTOs as Java records, they may be [shallowly immutable](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Record.html).\n\n## 1. Include the library in your project\n\n### 1.1 Maven\n\nIf you have a Maven project, add the dependency below to your `\u003cdependencies\u003e` tag in your `pom.xml`:\n\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.manoelcampos\u003c/groupId\u003e\n    \u003cartifactId\u003edtogen\u003c/artifactId\u003e\n    \u003c!-- Set a specific version or use the latest one --\u003e\n    \u003cversion\u003eDTOGEN_VERSION_HERE\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n### 1.2 Gradle\n\nAdd the following dependency into the build.gradle file of your Gradle project.\n\n```groovy\ndependencies {\n    //Set a specific version or use the latest one\n    implementation 'io.github.manoelcampos:dtogen:DTOGEN_VERSION_HERE'\n}\n```\n\n## 2. How to use\n\nNow, annotate the model classes you want to generate DTOs with `@DTO`.\nIf you annotated a `Person` class, a `PersonDTO` record will be generated in the same package.\n\n**WARNING**: Don't try to use the generated DTO before performing a successful build on the project (for instance, using `mvn clean package`). That is when the DTOs are generated. If you try to use them before that, the IDE may show an error saying the DTO doesn't exist.\n\nFinally, use the DTO record where you wish, but you may need to import the DTOs you are using. Since DTOs are generated in the same package as the annotated classes, you can import them using the `*` wildcard.\n\nIf you import the DTO individually, you may get a compiler error saying the DTO doesn't exist.\nUsually, you just need to build the project before trying to use any generated DTO,\nthen run the project (even if the IDE is showing some erros), that it may work after all.\n\nThe annotation processing will be automatically performed when you build your project, generating the DTOs for model classes that are annotation with `@DTO`.\n\nThe example below shows a `Person` model class (but it could be a record) which uses the `@DTO` annotation to generate a `PersonDTO` record. This is the only annotation required to create a DTO. By default, the DTO record will have the same fields from the model class. Other annotation such as `@NotNull` and `@NotBlank` are from Hibernate Validation and will be copied to the DTO fields. This way, you don't need to duplicate validation rules between the model class and the DTO.\n\n```java\n@DTO\npublic class Person {\n    private long id;\n\n    @NotNull @NotBlank\n    private String name;\n\n    @DecimalMin(\"0.1\") @DecimalMax(\"200\")\n    private double weightKg;\n\n    @Min(5) @Max(50)\n    private int footSize;\n\n    private String password;\n\n    private Country country;\n\n    private Profession profession;\n}\n```\n\nAfter that, build your project using, for instance, `mvn clean package`.\nThat will generate the following `PersonDTO` record in the same package as the `Person` class:\n\n```java\npublic record PersonDTO ( \n    long id, \n    @NotNull @NotBlank String name, \n    @DecimalMin(value=\"0.1\") @DecimalMax(value=\"200\") double weightKg, \n    @Min(value=5) @Max(value=50) int footSize,\n    String password,\n    Country country,  \n    Profession profession) implements DTORecord\u003cPerson\u003e\n{\n    @Override public Person toModel(){/*...*/}\n    @Override public PersonDTO fromModel(Person model){/*...*/}\n}\n```\n\nThe generated DTO provides implementations for the `toModel()` and `fromModel()` methods, that respectively, (i) converts the current DTO to a model class/record and (ii) converts a given model class/record to a DTO.\nThis way, you don't need to use additional libraries such as [MapStruct](https://mapstruct.org).\nFinally, the implementations of those methods follow a Convention-over-Configuration approach and works out-of-the-box.\n\n### 2.1 Additional Options\n\nYou can use `@DTO` sub annotations to configure how the DTO record is created. For instance, the `@DTO.Exclude` will exclude the annotated field from the DTO record.\n\nThe `@DTO.MapToId` can be used in fields in which the type is another model class,\nso that instead of including the entire object as an attribute in the DTO record,\nonly its id will be included. This way, placing this annotation on a `country` field will generate a `countryId` field on the DTO.\n\n```java\n@DTO.Exclude\nprivate String password;\n\n@DTO.MapToId\nprivate Country country;\n```\n\nThat will generate the following `PersonDTO` record:\n\n```java\npublic record PersonDTO ( \n    long id, \n    @NotNull @NotBlank String name, \n    @DecimalMin(value=\"0.1\") @DecimalMax(value=\"200\") double weightKg, \n    @Min(value=5) @Max(value=50) int footSize,\n    // password is not included in the generated DTO\n    @NotNull long countryId,  \n    Profession profession) implements DTORecord\u003cPerson\u003e\n{\n    @Override public Person toModel(){/*...*/}\n    @Override public PersonDTO fromModel(Person model){/*...*/}\n}\n```\n\n### 2.2 Working with Lombok\n\nIf you are using [Lombok](http://projectlombok.org), some adicional configuration is needed to ensure Lombok is executed before DTOGen.\nFor more details, check the [sample project pom.xml file](sample/pom.xml).\n\n### 2.3 Spring Boot\n\nIf you have a SpringBoot project, use the same configuration from the sample project, but don't exclude Lombok and DTOGen in the spring-boot-maven-plugin.\n\n## 3. Troubleshooting\n\nIf you try to use a DTO such as the `PersonDTO` in the example above, and the IDE shows an error saying it doesn't exist, follow the steps below:\n\n1. ensure your code compiles after you use the `@DTO` annotations and before including any DTO record on your code;\n2. enable the \"Annotation Processing\" in the IDE settings (that is required if you are using IntelliJ IDEA: usually a notification is shown when you open the project that has the library included);\n3. make sure you have imported the DTO record in the class where you are using it, as described in the end of Section 2 above (if you try to import the DTO record directly, instead of using the `*` wildcard, the IDE may show an error saying the DTO doesn't exist, but follow the steps below that it usually works);\n4. build the project using, for instance, `mvn clean compile` in the command line;\n5. after that, try to run the project (even if it is showing that the DTO records don't exist, usually after that they are generated and the code works).\n\n### 3.1 Other IntelliJ issues\n\nIf you try to open this entire repository on some IDEs such as IntelliJ,\nthe sample project won't generate the DTOs.\nYou must open just the sample project on the IDE for the annotation processing to work.\n\nIf you try to use some generated DTO, the IDE may show the DTO record doesn't exist, despite they are correctly generated in the target/generated-sources directory. If you face this issue, just press SHIFT+SHIFT on IntelliJ e type `Reload All Maven Projects` to reload the project settings.\n\nIf you still face issues, delete the `.idea` directory, close the project then the entire IntelliJ IDE (in such an order). Finally, reopen the project.\n\n\n#### 3.1.1 Error: Compilation failed: internal java compiler error\n\nIf you face this issue when using IntelliJ, check the following IDE setting:\n\n`Build, Execution, Deployment \u003e Maven \u003e Runner \u003e Delegate IDE build/run actions to maven`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanoelcampos%2Fdtogen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmanoelcampos%2Fdtogen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmanoelcampos%2Fdtogen/lists"}