[JAVA] Have you stopped thinking about using BeanUtils.copyProperties?

Java's "BeanUtils.copyProperties" is a very useful feature, Is it really being used properly?

This time I would like to talk about Entity, DTO and Form patterns.

See cases where Entity, DTO and Form are implemented as beans. But isn't the reason you just want to use "BeanUtils.copyProperties"?

For example, this implementation

class EntityBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}

class DtoBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}

class FormBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}

If you have the same field in Entity, DTO, Form, "BeanUtils.copyProperties" I think it's certainly possible and convenient to use.

But think twice. Isn't Entity, DTO, Form meant to absorb different implementations?

Having the same field because you want to use "BeanUtils.copyProperties" Isn't it forced? If that happens, it will not be resistant to changes, and the database specifications will be changed. You will have to continue to operate the Entity, DTO, and Form manually.

When the field name is changed due to the DB specification change

Changed to Entity value-> hoge.

class EntityBean
{
    private int hoge;
    public int getHoge(){ return hoge; }
    public void setHoge(int hoge){ this.hoge = hoge; }
}

class DtoBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}

class FormBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}

This will pass the build as long as you use "BeanUtils.copyProperties" There is a possibility that it will move as it is. To the person making the DTO and Form (maybe myself) You have to communicate and have it corrected. You'll also need test code to keep it working.

Where is it worth paying for this cost? Is there a mounting mistake?

If you can force (can) have the same field in 3 places of Entity, DTO, Form Inheritance is a good implementation.

class EntityBean
{
    private int hoge;
    public int getHoge(){ return hoge; }
    public void setHoge(int hoge){ this.hoge = hoge; }
}

class DtoBean extends EntityBean
{
}

class FormBean extends DtoBean
{
}

You can guarantee that you have the same fields, and at the code level if there are changes Be aware of build-time errors as they change.

Since it is inherited, if you want to remove the property, you can upcast it. There is no need to use "BeanUtils.copyProperties" at all.

But isn't having the same fields in Entity, DTO, and Form defeating the purpose in the first place?

This is what I really want to do.

class EntityBean
{
    //Entity has date as date type
    private DateTime date;
    public DateTime getDate(){ return date; }
    public void setDate(DateTime date){ this.date = date; }
}

class DtoBean
{
    //DTO has a date as a string type
    private String date;
    public String getDate(){ return date; }
    public void String(String date){ this.date = date; }
}

class FormBean
{
    //Form has dates by date
    private String year;
    private String month;
    private String day;
}

Because "Entity, DTO, Form" may have different implementations It's a division, and it doesn't make any sense if the same implementation is assumed. As long as you use "BeanUtils.copyProperties", it's low in abstraction and unprepared.

In the first place, who should be responsible for the conversion between "Entity" and "Form"? Are you reluctant to take responsibility by using "BeanUtils.copyProperties"?

By the way, in the case of the above example, who has the role of "DTO"? I don't think it's necessary. DTO is not needed unless it is entwined with multiple entities.

You really need another person to take on the role of converting "Entity" and "Form".

class EntityBean
{
    //Entity has date as date type
    private DateTime date;
    public DateTime getDate(){ return date; }
    public void setDate(DateTime date){ this.date = date; }
}

class Converter
{
   //This guy is responsible for preparing methods to convert to each other
   public static EntityBean convert(FormBean form) ...Implementation is omitted
   public static FormBean convert(EntityBean form) ...Implementation is omitted
}

class FormBean
{
    //Form has dates by date
    private String year;
    private String month;
    private String day;
}

If you use "BeanUtils.copyProperties" in "Converter" I think the level of abstraction is maintained.

Manually create the same fields in 3 places, Entity, DTO, Form "BeanUtils.copyProperties" is used as a precondition for designing. Isn't there a case around you?

Is that really correct? I am wondering. We look forward to hearing from you.

Recommended Posts

Have you stopped thinking about using BeanUtils.copyProperties?
Have you stopped thinking about using getters / setters in DTO design patterns?
Thinking about logic Ruby
Have you ever thought about the definition of "bad design"?