Skip to content

Instantly share code, notes, and snippets.

@Genzer
Created September 8, 2023 05:17
Show Gist options
  • Save Genzer/738d349be081167c62f81b64d26d1974 to your computer and use it in GitHub Desktop.
Save Genzer/738d349be081167c62f81b64d26d1974 to your computer and use it in GitHub Desktop.
package com.grokhard.exploring.java.mapstruct;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.NullValueCheckStrategy;
import org.mapstruct.NullValuePropertyMappingStrategy;
import org.mapstruct.factory.Mappers;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
public class MapStructProblemTest {
/**
* PROBLEM
* ----
* I need an implementation such that it is possible to merge one instance of
* SourceInput into another, then convert into FinalOutput.
*
* Sort of like
*
* ```
* FinalOutput converted = convert(merge(SourceInput a, SourceInput b))
* ```
*/
@Test
public void should_merge_then_map() {
SourceInput one = new SourceInput("One", null);
SourceInput two = new SourceInput(null, "2023-09-07");
FinalOutput finalOutput = MergingMapper.INSTANCE.mergeFrom(one, two);
assertEquals(finalOutput.getName(), one.getName());
assertEquals(finalOutput.getBirthday(), two.getBirthday());
}
@Mapper
public static interface MergingMapper {
public static final MergingMapper INSTANCE = Mappers.getMapper(MergingMapper.class);
// EXPLANATION:
// This method is the glue of other generated methods by MapStruct.
// Its implementation is kept as simple as possible.
public default FinalOutput mergeFrom(SourceInput a, SourceInput b) {
SourceInput merged = new SourceInput();
copy(a, merged);
copy(b, merged);
return toFinalOutput(merged);
}
// EXPLANATION:
// This method does the usual mapping from SourceInput to FinalOutput.
FinalOutput toFinalOutput(SourceInput source);
// See: https://stackoverflow.com/questions/68682925/using-mapstruct-to-fill-in-same-classes
@BeanMapping(
nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS
)
// EXPLANATION:
// This method serves as a copy-properties method from one SourceInput to another.
// It's important to note that the latter argument will be modified in-place and is returned.
SourceInput copy(SourceInput source, @MappingTarget SourceInput target);
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class FinalOutput {
private String name;
private String birthday;
}
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public static class SourceInput {
private String name;
private String birthday;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment