We added this to the OrganizationAdminMapper
for OrganizationCreateAdminRequest
:
@BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
Organization toEntity(OrganizationCreateAdminRequest organizationDTO);
Expected behavior: If organizationStatus
or organizationTier
is null
in the request, the default values defined in the entity (ACTIVE
, NOT_DETERMINED
) would remain untouched.
Reality: null
values overrode the defaults.
package com.sensey.fepatex.common.debug.task.organization;
import com.sensey.fepatex.common.debug.task.DebugTask;
import com.sensey.fepatex.domain.organization.dto.private_api.admin_api.request.OrganizationCreateAdminRequest;
import com.sensey.fepatex.domain.organization.entity.Organization;
import com.sensey.fepatex.domain.organization.entity.embedded.OrganizationContact;
import com.sensey.fepatex.domain.organization.entity.embedded.OrganizationFinance;
import com.sensey.fepatex.domain.organization.enums.OrganizationStatus;
import com.sensey.fepatex.domain.organization.enums.OrganizationTier;
import com.sensey.fepatex.domain.organization.enums.OrganizationType;
import com.sensey.fepatex.domain.organization.mapper.private_api.admin_api.OrganizationAdminMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import java.time.LocalDate;
@Component
@Profile("local")
@RequiredArgsConstructor
@Slf4j
public class OrganizationMapperDebugTask implements DebugTask {
private final OrganizationAdminMapper organizationAdminMapper;
@Override
public void execute() {
log.info(" Start OrganizationMapperDebugTask");
OrganizationCreateAdminRequest request = new OrganizationCreateAdminRequest(
"Acme Corp",
"12345678",
"<https://cdn.example.com/logo.png>",
"Manufacturing",
"Plastics",
LocalDate.of(2022, 1, 1),
"Long-term strategic partner.",
null,
null,
null,
null,
OrganizationType.CUSTOMER,
null,
new OrganizationContact(),
new OrganizationFinance()
);
Organization org = organizationAdminMapper.toEntity(request);
log.info(">>> Mapped Organization Entity");
log.info("Name: {}", org.getName());
log.info("KvK: {}", org.getCocNumber());
log.info("Status: {}", org.getOrganizationStatus());
log.info("Tier: {}", org.getOrganizationTier());
log.info("Type: {}", org.getOrganizationType());
if (org.getOrganizationStatus() == OrganizationStatus.ACTIVE) {
log.info("Default OrganizationStatus 'ACTIVE' applied");
} else {
log.warn("OrganizationStatus was not set to default value ACTIVE");
}
if (org.getOrganizationTier() == OrganizationTier.NOT_DETERMINED) {
log.info("Default OrganizationTier 'NOT_DETERMINED' applied");
}
else {
log.warn("OrganizationTier was not set to default value NOT_DETERMINED");
}
log.info(" End OrganizationMapperDebugTask");
}
}
>>> Mapped Organization Entity
Name: Acme Corp
KvK: 12345678
Status: null
Tier: null
Type: CUSTOMER
OrganizationStatus was not set to default value ACTIVE
OrganizationTier was not set to default value NOT_DETERMINED
@Builder.Default
@Enumerated(EnumType.STRING)
@JdbcType(PostgreSQLEnumJdbcType.class)
@Column(name = "organization_status", nullable = false)
private OrganizationStatus organizationStatus = OrganizationStatus.ACTIVE;
@Builder.Default
@Enumerated(EnumType.STRING)
@JdbcType(PostgreSQLEnumJdbcType.class)
@Column(name = "organization_tier", nullable = false)
private OrganizationTier organizationTier = OrganizationTier.NOT_DETERMINED;
public record OrganizationCreateAdminRequest(
String name,
String cocNumber,
String photoURL,
String primarySector,
String secondarySector,
LocalDate startDate,
String notes,
OrganizationStatus organizationStatus,
OrganizationSource organizationSource,
OrganizationTier organizationTier,
OrganizationDivision organizationDivision,
OrganizationType organizationType,
UUID accountManagerId,
OrganizationContact contact,
OrganizationFinance finance
) {}
Even with @BeanMapping(nullValuePropertyMappingStrategy = IGNORE)
, MapStruct still maps null
explicitly provided in the source DTO, effectively overriding the defaults in the target entity.