projectlombok / lombok

Very spicy additions to the Java programming language.
https://projectlombok.org/
Other
12.73k stars 2.36k forks source link

Support for an entirely new constructor generation #3701

Open codeleep opened 2 weeks ago

codeleep commented 2 weeks ago

For example I am using springboot related framework. I would create an Aform.

  1. When passing to the Service, it needs to be inserted into the database and it needs to be converted to AEntiy.
  2. When the front end queries, I will convert AEntiy to AVo. It is certainly achievable using mapstruct current approach. But I want to have a whole new way of doing this without creating a Mapper interface.

Below I will describe my idea:

Suppose I have the following three java beans


/**
** AForm
**/
public class AForm {
    private String name;
    private Long age;
}

/**
** AEntiy
**/
public class AEntiy {
    private String name;
    private Long age;
}

/**
** AVo
**/
public class AEntiy {
    private String name;
    private Long age;
}

I hope they can want to change between the conversion. Then I manually add the corresponding pair constructor

/**
** AForm
**/
public class AForm {
    private String name;
    private Long age;

    public AForm(AEntiy aEntiy) {
        if (aEntiy == null) {
            return;
        }
        this.setName(aEntiy.getName());
        this.setAge(aEntiy.getAge());
    }

    public AForm(AVo aVo) {
        if (aVo == null) {
            return;
        }
        this.setName(aVo.getName());
        this.setAge(aVo.getAge());
    }
}

/**
** AEntiy
**/
public class AEntiy {
    private String name;
    private Long age;

   public AEntiy(AForm aForm) {
        if (aForm == null) {
            return;
        }
        this.setName(aForm.getName());
        this.setAge(aForm.getAge());
    }

    public AEntiy(AVo aVo) {
        if (aVo == null) {
            return;
        }
        this.setName(aVo.getName());
        this.setAge(aVo.getAge());
    }
}

/**
** AVo
**/
public class AVo {
    private String name;
    private Long age;

    public AVo(AForm aForm) {
        if (aForm == null) {
            return;
        }
        this.setName(aForm.getName());
        this.setAge(aForm.getAge());
    }

    public AVo(AEntiy aEntiy) {
        if (aEntiy == null) {
            return;
        }
        this.setName(aEntiy.getName());
        this.setAge(aEntiy.getAge());
    }
}

As you can see, when I create different constructors, I can use the new keyword to create corresponding data. But if I write this code manually it makes it very clunky.

Therefore, I hope that the corresponding annotation can be added and the corresponding code can be automatically generated. Such:

/**
** AForm
**/
@BeanMappingConstructor({ AEntiy.class , AVo.class})
public class AForm {
    private String name;
    private Long age;
}

/**
** AEntiy
**/
@BeanMappingConstructor({ AForm.class , AVo.class})
public class AEntiy {
    private String name;
    private Long age;
}

/**
** AVo
**/
@BeanMappingConstructor({ AEntiy.class , AForm.class})
public class AVo {
    private String name;
    private Long age;
}

Of course, I just provided an idea to simplify the conversion. As for more details, I haven't considered them yet.

janrieke commented 1 week ago

This is going to be a hell of a maintenance burden, as this probably needs resolution. Furthermore, it is going to become complicated very quickly: Just think of differently named fields or type mappings.

Mapstruct is the way to go here. It's simply too complex for Lombok.

PS: I'm just a contributor, not a project maintainer, so that's just an opinion. But I doubt the maintainers will come to a different assessment.

codeleep commented 1 week ago

This is going to be a hell of a maintenance burden, as this probably needs resolution. Furthermore, it is going to become complicated very quickly: Just think of differently named fields or type mappings.

Mapstruct is the way to go here. It's simply too complex for Lombok.

PS: I'm just a contributor, not a project maintainer, so that's just an opinion. But I doubt the maintainers will come to a different assessment.

I can't be sure whether to attribute him to mapstruct or lombok. I did submit that idea at both repositories.

In view of the purpose of use, he really belongs to mapstruct. Because I just want to be able to convert objects in a minimalist way.

But from experience, I think lombok is more capable in this regard, similar to @AllArgsConstructor @EqualsAndHashCode. All generate specified code in the current class.