Define default value for inherited class using lombok

Viewed 249

So I am developing a notification service which, for now, only has a Notification and an Email entity, where Email extends Notification.

The Notification entity has a column named type which stores the type of the notification (ie: EMAIL, MESSAGE, PUSH, etc) and I want to know if there is a way to define a default value for the type column for each of the childs of Notification while using lombok.

I see that a common practice is to set the type on the constructor, like this:

public Email() {
    setType("EMAIL");
}

But I am using the builder from lombok to instatiate Email, like this:

public static Email fromEmailRequest(final EmailRequest emailRequest) {
        if (Objects.isNull(emailRequest)) {
            return Email.builder().build();
        }
        Set<String> set = new LinkedHashSet<>(emailRequest.getRecipients());
        return Email.builder()
                .content(emailRequest.getContent())
                .recipients(Lists.newArrayList(set))
                .sender(emailRequest.getSender())
                .subject(emailRequest.getSubject())
                .type(NotificationTypeEnum.EMAIL)
                .build();
}

The approach I am using now sets the type in the request DTO mapper, but I think this logic should be somewhere in the entities.

1 Answers

Maybe there is a better way, but you can create a constructor inside your Notification class which has the type as parameter and then manually create an all args constructor for your Email class. Lombok will use this constructor for the builder instead of generating one.

public class Notification {

    private final String type;

    protected Notification(String type) {
        this.type = type;
    }
}

@Builder
public class Email extends Notification {

    private String test;

    private Email(String test) {
        super("EMAIL");
        this.test = test;
    }
}

@SuperBuilder is a bit more complex to work with, but the idea is the same. You can still write parts of the code that is normally generated by lombok yourself and change its behavior with your own code.

So you implement the build method yourself and set the type to EMAIL.

@SuperBuilder(toBuilder = true)
public class Email extends Notification {

    private String test;

    public static class EmailBuilderImpl extends EmailBuilder<Email, EmailBuilderImpl> {
        /* Make sure the value is never accidently set to something other than `EMAIL`*/
        @Override
        public EmailBuilderImpl type(String type) {
            if (!type.equals("EMAIL")) {
                throw new UnsupportedOperationException();
            }
            return super.type(type);
        }

        public Email build() {
            return new Email(type("EMAIL"));
        }
    }
}
Related