I have a hierarchy of DTO classes created by lombok @SuperBuilder
. When using it, one of the fields becomes mysteriously renamed. Why is that and what can I do to maintain the original name ? Is this a lombok problem or feature - but I cannot find any hints in the lombok docs?
@SuperBuilder
@Getter
@NoArgsConstructor
public class ExpenseDto {
@NonNull
@Size(max = 30)
protected String recipient;
@NonNull
@Size(max = 30)
protected String purpose;
// ...
protected boolean isInvoiced; // this somehow is changed
}
@Data
@EqualsAndHashCode(callSuper = true)
@SuperBuilder
public class ExpenseEntityDto extends ExpenseDto {
@Size(max = 16)
long expenseId;
@Size(max = 16)
@NonNull
protected String accountNo;
// ...
}
I use it like so:
public ExpenseEntityDto domainToEntityDto(Expense domain) {
return ExpenseEntityDto.builder()
.expenseId(domain.getExpenseId())
.accountNo(domain.getAccountNo())
.recipient(domain.getRecipient())
.purpose(domain.getPurpose())
.isInvoiced(domain.isInvoiced()) // produces a field 'invoiced' !?
.build();
}
In flight, the DTO JSON looks like this:
{
"recipient": "Mobsters Inc.",
"purpose": "protection services rendered",
"expenseId": 1,
"accountNo": "1234",
"invoiced": false // Huh !? expected 'isInvoiced' instead
}
Even better, the openapi spec (generated from smallrye-openapi extension in quarkus) shows BOTH versions in the Schema (same in swagger ui):
ExpenseEntityDto:
type: object
properties:
recipient:
maxLength: 30
type: string
purpose:
maxLength: 30
type: string
isInvoiced:
type: boolean
invoiced:
type: boolean
expenseId:
format: int64
type: integer
accountNo:
maxLength: 16
type: string
You did ofcourse read the documentation?
For
boolean
fields that start withis
immediately followed by a title-case letter, nothing is prefixed to generate the getter name.
This is default Lombok behavior (and not sure if that is overridable). Lombok follows the Java Beans spec as close as possible. A boolean field named isInvoiced
would get an accessor like isIsInvoiced
which is confusing, hence it doesn't generate an additional is
.
Looking at the Java Bean specification all fields will be prefixed with get
or set
depending on the type. With one exception that is boolean
that instead of get
will be prefixed with is
.
To get an getIsInvoiced
you would need to make the field a Boolean
field instead of a boolean
.
Another option is to add Jackson annotations to force the field in JSON to be isInvoiced
(adding a @JsonProperty("isInvoiced")
to the field should take care of that.