Mapstruct ignore method generation - methods

Is there a way to ignore the generation of the mapper for the 3rd method in this code sample using mapstruct?
#Mapper(unmappedSourcePolicy = ReportingPolicy.IGNORE, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface EmployeeMapper {
EmployeeMapper MAPPER = Mappers.getMapper( EmployeeMapper.class );
#Mapping(source = "id", target = "id")
#Mapping(source = "firstName", target = "firstname")
#Mapping(source = "surname", target = "surname")
#Mapping(source = "employmentses", target = "employmentDTOList")
EmployeeDTO employee2dto(Employees employees);
#Mapping(source = "id", target = "id")
#Mapping(source = "firstName", target = "firstname")
#Mapping(source = "surname", target = "surname")
#Mapping(target = "employmentDTOList", ignore = true)
EmployeeDTO domainView2dto(EmployeeView employeeView);
//to be ignored by Mapstruct
EmployeePageDTO domainPage2dto(Page<EmployeeView> employeeViewPage);
}

You can simply define a default method inside the interface as stated here:
#Mapper(unmappedSourcePolicy = ReportingPolicy.IGNORE, unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface EmployeeMapper {
EmployeeMapper MAPPER = Mappers.getMapper( EmployeeMapper.class );
//.....
//to be ignored by Mapstruct
default EmployeePageDTO domainPage2dto(Page<EmployeeView> employeeViewPage) {
//.... insert body here
}
}

Related

How to customized and Override Parameter Values from POJO?

I am working on Spring Boot v2.2.6.RELEASE and Open API Integration example. This example has capability to search using 20 different parameters. So this POJO class holds CustomSearchDto these 20 different values.
In the POJO I used orgName, but #parameter(in = ParameterIn.QUERY, name = "orgizationName", and somehow I wanted to override the variable name. I must do that. Is there any way to do it ?
#Parameter(in = ParameterIn.QUERY, name = "orgizationName", schema = #Schema(type = "string"))
#Parameter(in = ParameterIn.QUERY, name = "employeeId", schema = #Schema(type = "string"))
#Parameter(in = ParameterIn.QUERY, name = "emailId", schema = #Schema(type = "string"))
#Parameter(in=ParameterIn.QUERY, name="page", description="Results page you want to retrieve (0..N)", schema=#Schema(defaultValue = "0"))
#Parameter(in=ParameterIn.QUERY, name="size", description="Number of records per page.", schema=#Schema(defaultValue = "30"))
#GetMapping(value = "/employees/organizations")
public ResponseEntity<PagedModel<Employees>> search(CustomSearchDto requestparams,
#Parameter(hidden=true) Pageable pageRequest) {
......
........
return new ResponseEntity<>(model, HttpStatus.OK);
}
Here is my custom DTO class
public class CustomSearchDto {
#Schema(description = "", type = "string", example = " ")
private String orgName;
#Schema(description = "", type = "string", example = " ")
private String empId;
#Schema(description = "", type = "integer", example = "null")
private Integer email;
.........
..............
.............
}
You can pass directly you object CustomSearchDto with the annotation #ParameterObject.
Here is the link for the documentation:
https://springdoc.org/faq.html#how-can-i-extract-fields-from-parameter-object-

MapStruct: mapping from object with a list of complex object

Supposing I have the following classes:
public class A {
private String id;
private List<B> related;
}
public class B {
private String id;
private String name;
}
public class ADTO {
private String id;
private List<BDTO> relations;
}
public class BDTO {
private String identificator;
private String relatedName;
}
How can I create a mapper that given an A object type returns me an ADTO object with all the information? I have to create two different mappers? Can it be done in only one mapper? I think it would be something like the following, but I don't know how to map the atributtes from the list:
#Mapper
public interface MyMapper {
#Mappings({ #Mapping(source = "related", target = "relations") })
ADTO mapperA(A obj);
}
Thanks in advance.
try this (not tested but should work properly)
when you mapping lists you should make a map for both the class element and the list to map all the elements of the list)
#Mapper
public interface MyMapper {
#Mappings({ #Mapping(source = "related", target = "relations") })
ADTO mapperA(A obj);
#Mappings(
{ #Mapping(source = "id", target = "identificator") },
{ #Mapping(source = "name", target = "relatedName") })
BDTO bDTOMapping(B b);
List<BDTO> bDTOListMapping(List<B> bList);
}

#valid #requestBody kotlin with entity into entity

I have a problem with valid request in kotlin because I currently have an object composed of a list of integers and another entity called emailData, when I send incomplete or in error format emaildata, the validation does not happen and let me enter the controller. my code this and my request in postman these
fun sendMessage(#Valid #RequestBody notificationData: NotificationData) {
this.notificationManager.sendNotificationByType(notificationData)
}
data class NotificationData(
#get:NotEmpty
#get:NotNull
#field:NotNull
#Size(min = 2, max = 14)
#get:JsonProperty("notification_type")
var notificationType : List<Int> = listOf(),
#Valid
//# #field:NotEmpty(message = "SRTERST enter id")
#get:JsonProperty("email_data")
var emailData : EmailData = EmailData())
data class EmailData(
#NotNull
#get:NotEmpty
#get:JsonProperty("email_receiver")
var emailReceiver : List<String> = listOf(),
#NotNull
#get:NotEmpty
#get:JsonProperty("subject")
var subject : String = "",
#get:NotEmpty
#NotNull
#get:JsonProperty("template_id")
var templateId : String = "",
#get:NotEmpty
#NotNull
#get:JsonProperty("template_params")
var templateParams : HashMap<String, String> = HashMap())
when i send
{
"notification_type":["0"],
"email_data":{
"subject":"test",
"template_id":"d-1860fd6fa461449b88c578b124a0b331"
}
}
the validation for the emailData no work.

MockMvc PostRequest Exception

I have following post mapping.
#PostMapping(value = BULK_UPDATE)
#ApiOperation(value = "Bulk Update of Markets by pairs of Market Key and Tier Quantity Id", tags = "Bulk", code = 200)
#ApiImplicitParams({
#ApiImplicitParam(name = "MarketTierQuantityId", value = "List of Market Key and Tier Quantity Id pairs",
paramType = "body", allowMultiple = true, dataType = "MarketTierQuantityId", required = true) })
#ApiResponses({
#ApiResponse(code = 200, message = "Bulk update successful", response = MarketStatus.class, responseContainer = "List") })
#ResponseStatus(org.springframework.http.HttpStatus.OK)
public ResponseEntity<StreamingResponseBody> bulkUpdate(
#RequestParam(name = IGNORE_SYNC_PAUSE_FAILURE, required = false, defaultValue = "false")
#ApiParam(name = IGNORE_SYNC_PAUSE_FAILURE, value = "Ignore failure of the jobs pause command") boolean ignoreJobsPauseFailure,
#RequestBody #ApiParam(name = "MarketTierQuantityId", value = "List of Market Key and Tier Quantity Id pairs", required = true) List<MarketTierQuantityId> marketTierQuantities,
#RequestParam(name = MOVE_TO_PREAUTH_FLAG, required = false, defaultValue = "true")
#ApiParam(name = MOVE_TO_PREAUTH_FLAG, value = "Move new units to Preauth for the markets with active waitlists") boolean moveToPreauth) throws BusinessException {
String requestId = getRequestId();
boolean jobsPaused = pauseJobs(ignoreJobsPauseFailure);
return LoggingStopWatch.wrap(() -> {
return ResponseEntity.ok().contentType(MediaType.APPLICATION_JSON)
.body(outputStream -> process(new SyncBulkProcessorHelper(outputStream),
marketTierQuantities, jobsPaused, requestId, moveToPreauth, LoggingStopWatch.create(LOGGER, "Bulk Update")));
});
}
and i have written the following test.
#RunWith(SpringRunner.class)
#WebMvcTest(BulkUpdateController.class)
#ContextConfiguration(classes = { BulkUpdateController.class, SharedExecutor.class })
#ActiveProfiles("dev")
public class BulkUpdateControllerTest {
#Autowired
private MockMvc mockMvc;
#MockBean
private BulkStatusService bulkStatusService;
#MockBean
private BulkMarketService bulkMarketService;
#MockBean
private HttpService httpService;
#MockBean
private RestClient restClient;
#MockBean
private BulkProcessorHelper helper;
#Test
public void test() throws Exception {
String request = TestHelper.getSerializedRequest(getBulkUpdateRequest(), MarketTierQuantityId.class);
mockMvc.perform(post("/bulkupdate").accept(MediaType.APPLICATION_JSON).contentType(MediaType.APPLICATION_JSON)
.content(request)).andExpect(status().is4xxClientError());
}
public MarketTierQuantityId getBulkUpdateRequest() {
MarketTierQuantityId market = new MarketTierQuantityId();
market.setMarketKey("00601|PR|COBROKE|POSTALCODE|FULL");
market.setTierQuantityId("10");
return market;
}
Getting the following error, have tried every possible way to resolve it but doesnt help.
Request failed. Error response:
{\"responseStatus\":{\"errorCode\":\"BadRequest\",\"message\":\"JSON
parse error: Cannot deserialize instance of java.util.ArrayList out
of START_OBJECT token\",\"stackTrace\":\"BusinessException(JSON parse
error:
P.S -> new to JUnits and mocks

mapping list source to target

I have an object organization that contains a contact objects list.
The conacts list exists already in the database.
To test with postman, when i need to add an organization i have to add the list of contacts id
{
"name": "ce",
"contactsId": [1, 3]
}
In the contact class i have
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "contact_organization", joinColumns = #JoinColumn(name = "contacts_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "organizations_id", referencedColumnName = "id"))
private Set<Organization> organizations = new HashSet<>();
In the Organization class i have
#ManyToMany(mappedBy = "organizations")
private Set<Contact> contacts = new HashSet<>();
and in the organisationDTO class i have
private Set<Long> contactsId = new HashSet<>();
In the mapping class i did the mapping this way but it doesn't seem to be working
#Mapper(componentModel = "spring", uses = { ContactMapper.class }))
public interface OrganizationMapper extends EntityMapper<OrganizationDTO, Organization> {
#Mapping(source = "contacts", target = "contactsId")
OrganizationDTO toDto(Organization organization);
#Mapping(source = "contactsId", target = "contacts")
Organization toEntity(OrganizationDTO organizationDTO);
default Organization fromId(Long id) {
if (id == null) {
return null;
}
Organization organization = new Organization();
organization.setId(id);
return organization;
}
default Long fromContact(Contact contact) {
return contact == null ? null : contact.getId();
}
}
#Mapper(componentModel = "spring", uses = { OrganizationMapper.class })
public interface ContactMapper extends EntityMapper<ContactDTO, Contact> {
ContactDTO toDto(Contact contact);
Contact toEntity(ContactDTO contactDTO);
default Contact fromId(Long id) {
if (id == null) {
return null;
}
Contact contact = new Contact();
contact.setId(id);
return contact;
}
}
the problem here it shows me the id and the label is null, and in the data base it adds the organization but does not add the contacts
Organization organization = organizationMapper.toEntity(organizationDTO);
for(Contact item : organization.getContacts()) {
log.info("******************************************" + item.getId());
log.info("++++++++++++++++++++++++++++++++++++++++++" + item.getLabel());
}
organization = organizationRepository.save(organization);
This currently is not supported. You are trying to map a property id from the list contacts into the contactsId list.
In order to achieve what you are looking forward you need to provide a way of mapping from Contact to Long.
Your mapper can look like:
#Mapper
public interface MyMapper {
#Mapping(source = "contacts", target = "contactsId")
OrganizationDTO toDto(Organization organization);
default Long fromContact(Contact contact) {
return contact == null ? null : contact.getId();
}
}

Resources