Karte ein dto zu einer Entität abgerufen aus der Datenbank, wenn die Dto hat Id mit MapStruct
Ich bin mit MapStruct zu machen dto <-> entity
mapping. Die gleichen Mapper werden verwendet, um erstellen und update Entitäten von dtos. Eine überprüfung der dto-id wird getan, um zu wissen, ob eine neue Person angelegt werden (id == null) oder sollte es abgerufen werden, aus der Datenbank (id != null) .
Ich bin tatsächlich mit MapperDecorator als workaround. Beispiel :
Mapper
@Mapper
@DecoratedWith(UserAccountDecorator.class)
public interface UserAccountMapper {
UserAccountDto map(User user);
User map(UserAccountDto dto);
User map(UserAccountDto dto, @MappingTarget User user);
}
Decorator
public abstract class UserAccountDecorator implements UserAccountMapper {
@Autowired
@Qualifier("delegate")
private UserAccountMapper delegate;
@Autowired
private UserRepository userRepository;
@Override
public User map(UserAccountDto dto) {
if (dto == null) {
return null;
}
User user = new User();
if (dto.getId() != null) {
user = userRepository.findOne(dto.getId());
}
return delegate.map(dto, user);
}
}
Aber diese Lösung wird schwer aufgrund der Tatsache, dass ein Dekorator erstellt werden muss für jeden mapper.
Gibt es eine gute Lösung zu führen, dass ?
Ich bin mit :
- MapStruct : 1.1.0
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich mein problem gelöst, indem Sie die folgenden Ratschläge, die von Gunnar in der Kommentar.
Zog ich zu MapStruct 1.2.0.Beta1 und erstellt eine UserMapperResolver wie unten
Welches ich dann in meine UserMapper :
Der generierte code ist nun :
Gut funktioniert !
@Autowired private UserRepository userRepository; @Autowired private PhoneREpository phoneRe; @ObjectFactory public User resolve(BaseUserDto dto, @TargetType Class<User> type) { User user = userRepository.findOne(dto.getId()); user.setPhone(phoneRep.getFIndOne(dto.getPhoneId())) return user; }
MapStruct allein kann das nicht tun. Allerdings mit einigen Generika und ein Haupt-abstrakte Klasse kann Ihr Leben leichter machen.
Müssen Sie eine generische Schnittstelle. Es muss nicht kommentiert werden mit
@Mapper
, weil, wenn es MapStruct wird versuchen, generieren eine Umsetzung und es wird scheitern. Es kann nicht generiert werden (generische Mapper.Dann müssen Sie eine
abstract
Klasse, wo haben Sie Ihre Logik.Dann jeder deiner Mapper wird nur verlängern müssen diese
abstract
Klasse.MapStruct generiert dann eine Umsetzung für die mapper-und Sie haben nur zu erweitern, die
AbstractGenericMapper
für die Zukunft. Natürlich benötigen Sie zur Anpassung der generischen Parameter, so kann man zumindest die id aus, die über eine Schnittstelle vielleicht. Wenn Sie verschiedene id-Typen, dann müssen Sie hinzufügen, dass der generische parameter derAbstractGenericMapper
als gut.null