GithubHelp home page GithubHelp logo

pozo / mapstruct-kotlin Goto Github PK

View Code? Open in Web Editor NEW
103.0 7.0 21.0 112 KB

Using mapstruct with kotlin data classes.

License: MIT License

Kotlin 66.49% Java 33.51%
kotlin mapstruct mapper annotation-processor java

mapstruct-kotlin's Introduction

mapstruct-kotlin

โš ๏ธ Since 1.4 MapStruct has support for using constructor arguments when instantiating mapping targets. This also works with Kotlin data classes.

Since mapstruct 1.3.0.Beta2 it's possible to use builders for immutable classes. According to the documentation you can implement your custom builder provider logic. This project take advantage of this and provide a custom BuilderProvider for kotlin data classes.

So instead of this (source)

data class PersonDto(var firstName: String?, var lastName: String?, var phone: String?, var birthdate: LocalDate?) {
    // Necessary for MapStruct
    constructor() : this(null, null, null, null)
} 

We can do this

@KotlinBuilder
data class PersonDto(val firstName: String, val lastName: String, val phone: String, val birthdate: LocalDate)

With a mapper

@Mapper
interface PersonMapper {
    fun map(person: Person): PersonDto
}

Usage

First apply kapt plugin

apply plugin: 'kotlin-kapt'

Then add these to your project as dependency

api("com.github.pozo:mapstruct-kotlin:1.3.1.2")
kapt("com.github.pozo:mapstruct-kotlin-processor:1.3.1.2")

Check out the directory example for a basic usage example.

Versioning

For example in case of 1.3.1.1 the first part 1.3.1 is the mapstruct version number and the last digit 1 reserved for future patches.

Project structure

  • mapstruct-kotlin-builder contains only the KotlinBuilder annotation
  • mapstruct-kotlin-processor responsible for generating the builders for the kotlin data classes with the help of a custom DefaultBuilderProvider
  • example responsible for demonstrating this library usage

Build and run the example application

./gradlew -p example clean build

TODO

  • Map with custom types are not working
  • Look over kotlin-builder-annotation project and replace with class generating module (builder-processor)
  • Writing tests
  • Versioning and release process

Licensing

Please see LICENSE file

Contact

Zoltan Polgar - [email protected]

Please do not hesitate to contact me if you have any further questions.

mapstruct-kotlin's People

Contributors

driver733 avatar gmribas avatar m-kay avatar mtraynham avatar pozo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

mapstruct-kotlin's Issues

Allow Builders to leverage Kotlin defaults, or kotlin builder notation when required fields are missing

ex data class in kotlin -

import com.github.pozo.KotlinBuilder

@KotlinBuilder
data class ContactInfo(val phoneNumbers: List<PhoneNumber> = emptyList(),
                       val emails: List<EmailAddress> = emptyList(),
                       val addresses: List<PostalAddress> = emptyList()
)

The create function within the generated builder looks like:

public ContactInfo create() { return new ContactInfo(phoneNumbers, emails, addresses); }

The create here uses an all args constructor. However, if the object builders never set a value for one mandatory field (addresses field, for example) the create() call using an all args constructor will try to set addresses to null, which will throw an NPE type error since this value can't be null in the target kotlin object.

I would like a way for the create() method to:

  • leverage the default values in Kotlin that an object may have (usually non-nullable types have this), setting a field to the default value if a default exists

This would be amazing and very helpful to generate more accurate builders!!

Missing imports for nested DTOs

Given:

@KotlinBuilder
data class A(var b: B?) {
    data class B(var name: String)
}

Expected:

public final class ContactInfoBuilder {
  public static CallbackApplication.ContactInfo builder() {
    return new CallbackApplication.ContactInfo();
  }
}

Actual:

public final class ContactInfoBuilder {
  public static ContactInfo builder() {
    return new ContactInfo();
  }
}

Useful links:
https://stackoverflow.com/questions/34271401/how-to-generate-inner-class-in-javapoet-in-java

https://github.com/square/javapoet/blob/master/src/test/java/com/squareup/javapoet/TypeSpecTest.java#L645

Mapping different data type for specific field

TL;DR:

Mapper

@Mapper
interface JobPostingMapper {
    @Mappings
    fun map(response: QuestionsResponse): Questions

    @Mappings
    fun map(model: Questions): QuestionsResponse
}

Domain

data class Questions(
    val questionSchema: QuestionSchema,
    val questionUiSchema: Map<String, Any>,
    val answer: Map<String, Any>
)

Data (DTO)

@Serializable
data class QuestionsResponse(
    @SerialName("question_schema")
    val questionSchema: QuestionSchema,
    @SerialName("question_ui_schema")
    val questionUiSchema: Map<String, JsonElement>,
    val answer: Map<String, JsonElement>
)

Does it possible to map different data type? as shown above JsonElement in DTO, Any in DOMAIN.

Because when trying the above case, error log thrown instead

Error Log

JobPostingMapper.java:11: error: Internal error in the mapping processor: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0  	at java.util.ArrayList.rangeCheck(ArrayList.java:659)  	at java.util.ArrayList.get(ArrayList.java:435)  	at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1165)  	at org.mapstruct.ap.internal.model.common.Type$TypeVarMatcher.visitDeclared(Type.java:1141)  	at com.sun.tools.javac.code.Type$ClassType.accept(Type.java:944)  	at javax.lang.model.util.AbstractTypeVisitor6.visit(AbstractTypeVisitor6.java:92)  	at org.mapstruct.ap.internal.model.common.Type.resolveTypeVarToType(Type.java:1136)  	at org.mapstruct.ap.internal.model.source.builtin.BuiltInMethod.matches(BuiltInMethod.java:70)  	at org.mapstruct.ap.internal.model.source.selector.TypeSelector.lambda$getMatchingParameterBinding$0(TypeSelector.java:158)  	at java.util.ArrayList.removeIf(ArrayList.java:1415)  	at org.mapstruct.ap.internal.model.source.selector.TypeSelector.getMatchingParameterBinding(TypeSelector.java:157)  	at org.mapstruct.ap.internal.model.source.selector.TypeSelector.getMatchingMethods(TypeSelector.java:71)  	at org.mapstruct.ap.internal.model.source.selector.MethodSelectors.getMatchingMethods(MethodSelectors.java:62)  	at org.mapstruct.ap.internal.processor.creation.MappingResolverImpl$ResolvingAttempt.getBestMatch(MappingResolverImpl.java:452)  	at org.mapstruct.ap.internal.processor.creation.MappingResolverImpl$ResolvingAttempt.getTargetAssignment(MappingResolverImpl.java:263)  	at org.mapstruct.ap.internal.processor.creation.MappingResolverImpl$ResolvingAttempt.access$100(MappingResolverImpl.java:158)  	at org.mapstruct.ap.internal.processor.creation.MappingResolverImpl.getTargetAssignment(MappingResolverImpl.java:139)  	at org.mapstruct.ap.internal.model.MapMappingMethod$Builder.build(MapMappingMethod.java:137)  	at org.mapstruct.ap.internal.model.PropertyMapping$PropertyMappingBuilder.forgeMapMapping(PropertyMapping.java:636)  	at org.mapstruct.ap.internal.model.PropertyMapping$PropertyMappingBuilder.forge(PropertyMapping.java:295)  	at org.mapstruct.ap.internal.processor.creation.MappingResolverImpl$ResolvingAttempt.getTargetAssignment(MappingResolverImpl.java:305)  	at org.mapstruct.ap.internal.processor.creation.MappingResolverImpl$ResolvingAttempt.access$100(MappingResolverImpl.java:158)  	at org.mapstruct.ap.internal.processor.creation.MappingResolverImpl.getTargetAssignment(MappingResolverImpl.java:139)  	at org.mapstruct.ap.internal.model.PropertyMapping$PropertyMappingBuilder.build(PropertyMapping.java:243)  	at org.mapstruct.ap.internal.model.BeanMappingMethod$Builder.applyPropertyNameBasedMapping(BeanMappingMethod.java:1211)  	at org.mapstruct.ap.internal.model.BeanMappingMethod$Builder.applyPropertyNameBasedMapping(BeanMappingMethod.java:1175)  	at org.mapstruct.ap.internal.model.BeanMappingMethod$Builder.build(BeanMappingMethod.java:259)  	at org.mapstruct.ap.internal.processor.MapperCreationProcessor.getMappingMethods(MapperCreationProcessor.java:375)  	at org.mapstruct.ap.internal.processor.MapperCreationProcessor.getMapper(MapperCreationProcessor.java:152)  	at org.mapstruct.ap.internal.processor.MapperCreationProcessor.process(MapperCreationProcessor.java:123)  	at org.mapstruct.ap.internal.processor.MapperCreationProcessor.process(MapperCreationProcessor.java:74)  	at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:338)  	at org.mapstruct.ap.MappingProcessor.processMapperTypeElement(MappingProcessor.java:318)  	at org.mapstruct.ap.MappingProcessor.processMapperElements(MappingProcessor.java:267)  	at org.mapstruct.ap.MappingProcessor.process(MappingProcessor.java:166)  	at org.jetbrains.kotlin.kapt3.base.incremental.IncrementalProcessor.process(incrementalProcessors.kt)  	at org.jetbrains.kotlin.kapt3.base.ProcessorWrapper.process(annotationProcessing.kt:147)  	at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor(JavacProcessingEnvironment.java:802)  	at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs(JavacProcessingEnvironment.java:713)  	at com.sun.tools.javac.processing.JavacProcessingEnvironment.access$1800(JavacProcessingEnvironment.java:91)  	at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run(JavacProcessingEnvironment.java:1043)  	at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing(JavacProcessingEnvironment.java:1184)  	at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1170)  	at com.sun.tools.javac.main.JavaCompiler.processAnnotations(JavaCompiler.java:1068)  	at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing(annotationProcessing.kt:79)  	at org.jetbrains.kotlin.kapt3.base.AnnotationProcessingKt.doAnnotationProcessing$default(annotationProcessing.kt:35)  	at org.jetbrains.kotlin.kapt3.base.Kapt.kapt(Kapt.kt:45)  	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)  	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)  	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)  	at java.lang.reflect.Method.invoke(Method.java:498)  	at org.jetbrains.kotlin.gradle.internal.KaptExecution.run(KaptWithoutKotlincTask.kt:158)  	at org.gradle.workers.internal.AdapterWorkAction.execute(AdapterWorkAction.java:57)  	at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:63)  	at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:67)  	at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:63)  	at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:97)  	at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:63)  	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)  	at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)  	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:409)  	at org.gradle.internal.operations.DefaultBuildOperationExecutor$CallableBuildOperationWorker.execute(DefaultBuildOperationExecutor.java:399)  	at org.gradle.internal.operations.DefaultBuildOperationExecutor$1.execute(DefaultBuildOperationExecutor.java:157)  	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:242)  	at org.gradle.internal.operations.DefaultBuildOperationExecutor.execute(DefaultBuildOperationExecutor.java:150)  	at org.gradle.internal.operations.DefaultBuildOperationExecutor.call(DefaultBuildOperationExecutor.java:94)  	at org.gradle.internal.operations.DelegatingBuildOperationExecutor.call(DelegatingBuildOperationExecutor.java:36)  	at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)  	at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:60)  	at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$2(DefaultWorkerExecutor.java:200)  	at java.util.concurrent.FutureTask.run(FutureTask.java:266)  	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:215)  	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)  	at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:131)  	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)  	at java.util.concurrent.FutureTask.run(FutureTask.java:266)  	at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)  	at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48)  	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)  	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)  	at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56)  	at java.lang.Thread.run(Thread.java:748)  
public abstract interface JobPostingMapper {

Data classes in another module

Hi, thanks a lot for this project!

I have a maven module with data classes all annotated with @KotlinBuilder and all the builders are successfully created and put into the jar.
I have another maven module that depends on the data classes and it tries to use mapstruct mapping these data classes to something.

During compilation kapt throws an error that "no parameterless constructor exists for type", basically, it doesn't see the builders but it does see the class itself. Not sure why is that, because they are both laying in the same folder in that jar.

May or may not be related to projectlombok/lombok#1538

Generates second setter when secondary constructor is defined at data class

When I add secondary constructor to data class, at builder class are two setter of the property.
My class

@KotlinBuilder
data class ProjectGroupModel(
    val parent: ProjectModel,
    val children: List<ProjectModel>
) : BaseAggregateRoot() {

    constructor(parent: ProjectModel) : this(parent, emptyList())

The result code

public final class ProjectGroupModelBuilder {
  private ProjectModel parent;

  private List<ProjectModel> children;

  private ProjectModel parent;

  public ProjectGroupModelBuilder setParent(ProjectModel parent) {
    this.parent = parent;
    return this;
  }

  public ProjectGroupModelBuilder setChildren(List<ProjectModel> children) {
    this.children = children;
    return this;
  }

  public ProjectGroupModelBuilder setParent(ProjectModel parent) {
    this.parent = parent;
    return this;
  }

  public ProjectGroupModel create() {
    return new ProjectGroupModel(parent, children, parent);
  }

  public static ProjectGroupModelBuilder builder() {
    return new ProjectGroupModelBuilder();
  }
}

As result I've got compilation error
ProjectGroupModelBuilder.java:10: error: variable parent is already defined in class ProjectGroupModelBuilder

KotlinBuilder generated by omitting the fields of the super class.

ex)
models

abstract class Audit(
    val createdBy: String = "", val createdAt: OffsetDateTime = OffsetDateTime.now(),
    val lastModifiedBy: String = "", val lastModifiedAt: OffsetDateTime = OffsetDateTime.now()
) : Serializable

@KotlinBuilder
data class UserGroup(
    val id: Long = -1,
    val name: String = "",
    val roles: List<Role> = emptyList()
) : Audit()

generated builder class

package com.kakao.mail.gateman.common.model;

import java.lang.String;
import java.util.List;

public final class UserGroupBuilder {
  private long id;

  private String name;

  private List<Role> roles;

  public UserGroupBuilder setId(long id) {
    this.id = id;
    return this;
  }

  public UserGroupBuilder setName(String name) {
    this.name = name;
    return this;
  }

  public UserGroupBuilder setRoles(List<Role> roles) {
    this.roles = roles;
    return this;
  }

  public UserGroup create() {
    return new UserGroup(id, name, roles);
  }

  public static UserGroupBuilder builder() {
    return new UserGroupBuilder();
  }
}

Therefore, it is impossible to map the suepr class field.

Does not fail if applied to non-data-class, and MapStruct just fails to create the mapper

Hi,

A MapStruct/mapstruct-kotlin issue:

When I forget to create my class as data class, but apply @KotlinBuilder then neither KotlinBuilder nor MapStruct produce an error during build, but MapStruct does not build the mapper. It just fails silently to do anything. This made it difficult to track down such issues.

If possible and easy, it would be really nice if @KotlinBuilder just fails if annotation is applied to non-data-class. Without @KotlinBuilder, MapStruct gives fine error about missing constructor.

Best Alex

Versions
api 'org.mapstruct:mapstruct:1.3.1.Final'
kapt 'org.mapstruct:mapstruct-processor:1.3.1.Final'
api "com.github.pozo:mapstruct-kotlin:1.3.1.1"
kapt "com.github.pozo:mapstruct-kotlin-processor:1.3.1.1"

Data class parameter named "default" gets weird mapping

Given a data class with a parameter named default, it get's mapped as a weird property name, like p0_772401952, where the p# part seems related to the index in which the parameter is in the constructor and 772401952 is some static int.

package com.pureport.kato.api

import com.github.pozo.KotlinBuilder

@KotlinBuilder
data class Foo(
    val default: Boolean
)

@KotlinBuilder
data class Foo2(
    val bar: String = "",
    val default: String
)

@KotlinBuilder
data class Foo3(
    val default: String,
    val bar: String = ""
)
package com.pureport.kato.api;

public final class FooBuilder {
  private boolean p0_772401952;

  public FooBuilder setP0_772401952(boolean p0_772401952) {
    this.p0_772401952 = p0_772401952;
    return this;
  }

  public Foo create() {
    return new Foo(p0_772401952);
  }

  public static FooBuilder builder() {
    return new FooBuilder();
  }
}
package com.pureport.kato.api;

import java.lang.String;

public final class Foo2Builder {
  private String bar;

  private String p1_772401952;

  public Foo2Builder setBar(String bar) {
    this.bar = bar;
    return this;
  }

  public Foo2Builder setP1_772401952(String p1_772401952) {
    this.p1_772401952 = p1_772401952;
    return this;
  }

  public Foo2 create() {
    return new Foo2(bar, p1_772401952);
  }

  public static Foo2Builder builder() {
    return new Foo2Builder();
  }
}
package com.pureport.kato.api;

import java.lang.String;

public final class Foo3Builder {
  private String p0_772401952;

  private String bar;

  public Foo3Builder setP0_772401952(String p0_772401952) {
    this.p0_772401952 = p0_772401952;
    return this;
  }

  public Foo3Builder setBar(String bar) {
    this.bar = bar;
    return this;
  }

  public Foo3 create() {
    return new Foo3(p0_772401952, bar);
  }

  public static Foo3Builder builder() {
    return new Foo3Builder();
  }
}

Invalid builder name for properties named "isXXX"

Hi,

thanks for your great work.
I've observed that for classes with isXXX properties the generated mapper doesn't include mapping of such properties.

For the following class

@KotlinBuilder
data class Animal(
    val isDog: Boolean
)

isDog property will not be mapped in the mapper.
I believe it might be caused by the difference in getter naming

For such a class isDog() method will be generated on the bytecode level (and setDog(boolean var) for var properties) However from what I see a setIsDog() method will be generated by the KotlinBuilder. There is a mismatch that can cause the MappingProcessor not to find the proper setter and just omitting the property.

Plan going forward

Hi,

This project seems to be first Kotlin-friendly attempt to model mapping. Since there is a new (final) release of MapStruct 1.3.0 do you have any plans to publish this library to the public?

Support for Typed POJO

I have an object that is generically typed, for example:

import com.github.pozo.KotlinBuilder

interface Bar

@KotlinBuilder
data class Foo<T : Bar>(
   val bar: T
)

When I build this, it generates the following:

public final class FooBuilder {
  private T bar;

  public FooBuilder setBar(T bar) {
    this.bar = bar;
    return this;
  }

  public Foo create() {
    return new Foo(bar);
  }

  public static FooBuilder builder() {
    return new FooBuilder();
  }
}

But it also dumps the following error:

  private T bar;
          ^
  symbol:   class T
  location: class FooBuilder/.../FooBuilder.java:6: error: cannot find symbol
  public FooBuilder setBar(T bar) {
                           ^
  symbol:   class T
  location: class FooBuilder

This seems very close and is simply missing the same type restriction on the Builder class.

JPA entity class issue

Hi
I think this project is very useful.
I have question.

How can I solve this if we write JPA entity as class (not data class)?
@KotlinBuilder annotation is only available in data class.

TYSM

Mapping of UUID to String error

I have an issue with Kotlin -> kapt -> mapstruct

I have 2 data classes

@entity(name = "PLAN")
@typedef(name = "pgsql_enum",
typeClass = PostgreSQLEnumType::class)
@KotlinBuilder
data class Plan(

    @Id
    @GeneratedValue(generator = "UUID")
    @GenericGenerator(name = "UUID", strategy = "org.hibernate.id.UUIDGenerator")
    @JsonProperty("uuid")
    val uuid: UUID? = null,

    @Column(nullable = false)
    val name: String,

...

@document(collection = "plan")
@KotlinBuilder
data class MongoPlan(

    val uuid: String? = null,

    val name: String,

....

and mapping instructions

@Mapper
interface MongoPlanMapper {

@Mappings(Mapping(target = "uuid",
        qualifiedByName = ["uuidMapper"]))
fun convert(plan: Plan): MongoPlan

@Named("uuidMapper")
fun uuidMapper(uuid: UUID): String =
        uuid.toString()

}

and I get

Error: java:".

Problem with ENUM

implementation("com.github.pozo:mapstruct-kotlin:1.3.1.1")
implementation("org.mapstruct:mapstruct:1.3.1.Final")
kapt("org.mapstruct:mapstruct-processor:1.3.1.Final")
kapt("com.github.pozo:mapstruct-kotlin-processor:1.3.1.1")
@Entity
class UserEntity(
        @Id
       var id: Long? = null,
      
        @Enumerated(EnumType.STRING)
        val type: ACCOUNT_TYPE)
@KotlinBuilder
data class UserDTO(val id: Long,
                   val type: ACCOUNT_TYPE)

enum class ACCOUNT_TYPE {
    S,
    M,
    C
}

error in generating builder class

public final class UserDTOBuilder {
  public UserDTO create() {
    return new UserDTO();
  }

  public static UserDTOBuilder builder() {
    return new UserDTOBuilder();
  }
}

DTO without Enum works perfect

Add support for Gradle incremental annotation processing

Add support for Gradle's incremental annotation processing with Kapt should help speed up build times. MapStruct is planning on this for 1.4.0, mapstruct/mapstruct#1971.

Currently kotlin users need to disable it with

kapt.incremental.apt=false

Theoretically, you'll likely just need to add a META-INF/services file that suggests that annotation processor is incremental.

src/main/resources/META-INF/gradle/incremental.annotation.processors

com.github.pozo.BuilderProcessor,isolating

https://docs.gradle.org/6.3/userguide/java_plugin.html#making_an_annotation_processor_incremental

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.