-
-
Notifications
You must be signed in to change notification settings - Fork 967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Kotlin data classes and mapstruct #1672
Comments
I had a brief look at the repository. The idea is OK. However, I think that implementing #73 is the correct way for implementing this. When MapStruct can use constructors for creating objects there won't be any difference between a normal Java class with constructor and Kotlin data classes. What do you think about #73? |
@filiphr any news on that? |
@Pozo i like your approach. It looks ok for now. Do you have plans to release it? |
Why not just add default params to primary constructor? data class Person(
var firstName: String? = null, // may be not only null
var lastName: String? = null,
var phoneNumber: String? = null,
var birthdate: LocalDate? = null
) In this case default constructor also will be created |
@gildor data class Person(
val firstName: String,
val lastName: String,
val phoneNumber: String,
val birthdate: LocalDate
) |
@filiphr Thank you for the information. I read through the #73 and I must agree with you. That would be a more generic way to achieve immutable class mapping, however my work was focusing on Kotlin’s data classes. When I started the implementation I’ve found #847 PR which seemed abandoned, and a few comments #73 (comment) #73 (comment) about the difficulties of a generic solution, so I decided to go only for Kotlin’s data classes. @ahulyk Thank you for your interest, however as I mentioned this is only a proof of concept right now. I just want to see how many people agree with this idea so I don’t plan to create any release yet. @gildor Thank you four your suggestion, however in this case I'm agreeing with @ahulyk, When I’m using pure Kotlin I really want to avoid something like you just wrote. I understand that it’s working but I think we should use Kotlin in an idiomatic way when It’s possible and one of It’s strengths is the immutability by default. |
@FearlessHyena I decided to push it a bit forward. I've made several adjustment on the repository today, so you can try it out with the help of jitpack.io. Don't forget to raise a ticket or open an issue if you have something to share. |
@Pozo This is great!!! :D |
@Pozo works for me, thank you!
Also, it creates an empty folder under |
Hi @Pozo I've been using it for a few weeks now and haven't seen any issues |
Hey, @Pozo one more vote for production! |
@Pozo +1 |
I would make 1 comment: instead of |
@Pozo, +1 |
Found one thing:
generates this:
Which does not compile because method
note: hand-written examples |
I appreciate your interest guys but we should keep this thread clean. To my mind this topic is only for collecting ideas about mapstruct with kotlin, and my approach is just one implementation. So if you have an issue/idea with my approach please create a ticket there. In this case others can find the relevant information more easily. |
It's been open for almost a year. Any plans on it? |
For sure.. To do it right is a major piece of work and we sure like to have it. But it is not as simple as the abandoned PR suggests 😄. I even think @filiphr was working on it. |
I just released https://github.com/Pozo/mapstruct-kotlin to the maven central. @filiphr I think we can close this issue. |
Since 1.4 MapStruct has support for using constructor arguments when instantiating mapping targets. This also works with Kotlin data classes. Therefore, I am closing this issue |
@filiphr It works good on Entity(not data class) -> DTO(data class). Or if I missed something please let me know what is wrong. version: mapstruct 1.4.2.Final |
@HomoEfficio I do not know much about Kotlin, but looking at the difference between I have no idea how the generated constructor looks like for this class in Kotlin. We are only looking into what the Java compiler sees and we use that. |
@filiphr As you can see in the upper right side of the picture, values of DTO( So to fix this issue, why don't you use constructor with params instead of default constructor with setters to create an Entity, just like creating DTO with constructor with params. Then It will work OK regardless of |
The problem with Kotlin classes is when all contructor properties are optional: data class User(
val id: UUID? = null,
val email: String? = null,
val phoneNumber: String? = null
) In this case compiler creates additional parameterless constructor which Mapstruct will use then by design, and so no actual mapping happens: User user = new User();
return user; As a possible workaround we can directly annotate data class constructor: data class User @Default constructor(
val id: UUID? = null,
val email: String? = null,
val phoneNumber: String? = null
) But moving this annotation to domain layer just for compatibility with some infrastructure code seems to be very wrong. My proposal is to add special Mapper parameter to avoid choosing empty constructor as default one when another with params exists. This should help in most cases. |
Still reproduces :( |
@HomoEfficio we can't do that due to backwards compatibility. I think that for your example there is more than one constructor visible to us.
This is not as trivial as you think @cujo. I would suggest that you follow #2378 that is meant to address this particular problem. |
Related to #1298 and #782
A few months ago I came to the same conclusion with the
all-open
and theno-arg
plugin like @thePhil and @nilotpal1981. However I really wanted to avoid using something likeLuckily since mapstruct 1.3.0.Beta2 it's possible to use builders for immutable classes. According to the documentation we can implement our custom builder provider logic. And the holiday season just came :) and I could create a proof of concept which is focusing on Kotlin's data classes.
So you can write down something like this:
The main idea is generating a builder for each data class and pass these builders to mapstruct via a custom
BuilderProvider
.As I mentioned this is a proof of concept repository but I want to develop it further. If you think that this might be a way to use mapstruct with kotlin please share your idea or request and create an Issue here:
https://github.com/Pozo/mapstruct-kotlin
The text was updated successfully, but these errors were encountered: