当我尝试实现自己的映射时,我在使用 MapStruct 版本 1.4.1 时遇到问题。这是我写的代码:
package com.kucazdravlja.user.mappers;
import com.kucazdravlja.user.dto.NoticeBoardDto;
import com.kucazdravlja.user.entities.NoticeBoard;
import com.kucazdravlja.user.entities.NoticeBoardStatus;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Named;
import java.util.Objects;
@Mapper(uses = {BaseJournalMapper.class})
public interface NoticeBoardMapper {
@Mapping(source = "status", target = "status", qualifiedByName = "getNoticeBoardStatusName")
NoticeBoard dtoToEntity(NoticeBoardDto noticeBoardDto);
@Mapping(source = "status", target = "status", qualifiedByName = "getNoticeBoardStatusDescription")
NoticeBoardDto entityToDto(NoticeBoard noticeBoard);
@Named("getNoticeBoardStatusDescription")
static String getNoticeBoardStatusDescriptionConverter(NoticeBoard noticeBoard) {
return Objects.requireNonNull(NoticeBoardStatus.findByName(noticeBoard.getStatus())).getDescription();
}
@Named("getNoticeBoardStatusName")
static String getNoticeBoardStatusNameConverter(NoticeBoardDto noticeBoardDto) {
return Objects.requireNonNull(NoticeBoardStatus.findByName(noticeBoardDto.getStatus())).name();
}
}
Run Code Online (Sandbox Code Playgroud)
运行应用程序时它崩溃并给出错误
Error:(15, 5) java: Qualifier error. No method found …Run Code Online (Sandbox Code Playgroud) 我有以下类和映射器来映射它们。如何将 Mapstruct 配置为“不”使用 Lombok 构建器?(不删除@Builder注释)?当使用最新版本的Lombok和mapstruct时,mapstruct在使用@Builder注解时会自动使用Builder。我找不到禁用它的方法,因为我需要 @AfterMapping 方法中的实例,因为构建器没有公开所有必需的方法(在此用例中不允许 @SuperBuilder)
@Entity(name = "user_details")
@Data
@Builder
public class User extends AuditableEntityBase {
@Version
@NotNull
private Integer version;
@NotNull
private String name;
@NotNull
private String email;
@NotNull
private Address address; // Just another Class containing another class that is mapped as well.
}
@Value
@Builder
public class UserDto extends AuditableEntityBaseDto {
@NotNull
private Integer version;
@NotNull
private String name;
@NotNull
private String email;
@NotNull
private AddressDto address;
}
@Mapper(componentModel = "spring")
class UserRestMapper { …Run Code Online (Sandbox Code Playgroud) 我努力寻找并实施以下问题的最佳实践:引发创建域事件(通知创建聚合的事件)的最佳位置在哪里。例如,如果我们在有界上下文中有订单聚合,我们希望在创建订单时通知所有感兴趣的各方。该事件可以是OrderCreatedEvent。
我首先尝试的是在构造函数中引发此事件(我在每个聚合中都有一个域事件集合)。这样只有我们创建订单的时候才可以。因为当我们将来想对这个聚合做任何事情时,我们将通过构造函数创建它的新实例。然后OrderCreatedEvent将再次引发,但事实并非如此。
但是,我认为在应用程序层中引发事件是可以的,但这是一种反模式(域事件应该只存在于域中)。也许可以选择使用一个Create方法,将 OrderCreatedEvent 添加到其域事件列表中,并在创建订单时在应用程序层中调用它。
我在互联网上发现的有趣事实是,在构造函数中引发域事件是一种反模式,这意味着最后描述的选项(具有Create 方法)将是最好的方法。
我使用 Spring Boot 作为应用程序,使用 MapStruct 作为将数据库/存储库实体映射到域模型聚合的映射器。此外,尝试找到一种方法来创建一个映射器,该映射器将跳过目标类的构造函数,但由于 Order 聚合的所有属性都是私有的,这似乎是不可能的。
如何将String映射到List和List to String?
考虑一下我们跟随classess
class People{
private String primaryEmailAddress;
private String secondaryEmailAddress;
private List<String> phones;
//getter and setters
}
class PeopleTO{
private List<String> emailAddress;
private String primaryPhone;
private String secondaryPhone;
//getter and setters
}
Run Code Online (Sandbox Code Playgroud)
在Dozer和Orika中,我们可以使用以下代码行轻松映射
fields("primaryEmailAddress", "emailAddress[0]")
fields("secondaryEmailAddress", "emailAddress[1]")
fields("phones[0]", "primaryPhone")
fields("phones[1]", "secondaryPhone")
Run Code Online (Sandbox Code Playgroud)
我如何在MapStruct中进行相同类型的映射?我会在哪里找到有关mapstruct的更多示例?
我想将对象列表映射到包含列表的对象:
public class Group {
private List<Person> people;
}
public class Person {
private String name;
}
Run Code Online (Sandbox Code Playgroud)
我尝试创建一个这样的映射器:
Group toGroup(List<Person> people);
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
error: Can't generate mapping method from iterable type to non-iterable type.
Run Code Online (Sandbox Code Playgroud)
这种映射最优雅的解决方案是什么?
我有下一堂课:
映射器
public interface DeviceTokensMapper {
DeviceTokensMapper INSTANCE = Mappers.getMapper(DeviceTokensMapper.class);
@Mappings({
@Mapping(source = "tokenName", target = "tokenName"),
@Mapping(source = "userOsType", target = "osType"),
})
DeviceTokensDTO toDeviceTokensDTO(DeviceTokens deviceTokens);
}
Run Code Online (Sandbox Code Playgroud)
实体:
@Entity
public class DeviceTokens {
@Id
@Column(name="token_name", nullable = false)
private String tokenName;
@Column(name = "os", nullable = false)
@Enumerated
private UserOSType userOsType;
public DeviceTokens() {}
public DeviceTokens(String tokenName, UserOSType userOSType) {
this.tokenName = tokenName;
this.userOsType = userOSType;
}
public String getTokenName() {
return tokenName;
}
public void setTokenName(String tokenName) { …Run Code Online (Sandbox Code Playgroud) 我有下面的映射器类,我想在其中使用CounterService. 我正在尝试构造函数注入,但这不起作用并且null正在打印。
@Mapper(componentModel = "spring", uses = CounterService.class, injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public abstract class CarMapper {
private CounterService counterService;
public CarMapper(CounterService counterService) {
this.counterService = counterService;
}
public abstract Car dtoToEntity(CarDto carDto);
public CarDto entityToDto(Car car) {
System.out.println(counterService)
//....
return carDto;
}
}
Run Code Online (Sandbox Code Playgroud)
实现类由mapStruct
@Component
public class CarMapperImpl extends CarMapper{
@Override
public Car dtoToEntity(CarDto carDto){
//...
}
}
Run Code Online (Sandbox Code Playgroud)
如果我使用字段注入@AutoWired,那么它就可以正常工作。这意味着Spring不支持abstract类的构造函数注入。是不是因为abstract类不能直接实例化,需要子类来实例化?
有什么方法mapStruct可以在实现类中创建构造函数,如下所示:
public CarMapperImpl(CounterService counterService){
super(counterService);
}
Run Code Online (Sandbox Code Playgroud)
这样,构造函数注入应该可以工作。
我正在尝试在 Spring Cloud 项目中创建非常简单的 JUnit 测试:
@SpringBootTest(classes = {ProductMapper.class })
public class TestingWebApplicationTests {
@Test
public void contextLoads() {
}
}
import org.mapstruct.Mapper;
@Mapper(config = BaseMapperConfig.class)
public interface ProductMapper {
ProductDTO toDTO(Product product);
ProductFullDTO toFullDTO(Product product);
Product map(ProductFullDTO productDTO);
ProductFilter toFilter(ProductFilterDTO dto);
}
Run Code Online (Sandbox Code Playgroud)
当我尝试在最新的 Intelij 中运行测试时,出现此错误。
java:由于错误元素 java.util.ArrayList 中存在问题,因此未为 ProductMapper 创建任何实现。提示:这通常意味着其他一些注释处理器应该处理错误的元素。您还可以通过设置 -Amapstruct.verbose=true 作为编译参数来启用 MapStruct 详细模式。
你知道我该如何解决这个问题吗?
我有Object1和Object2.现在,我想映射object3,其中包含1和2的属性.
说,我有2个对象:
1. User: {first_name, last_name, id}
2. Address: {street, locality, city, state, pin, id}
Run Code Online (Sandbox Code Playgroud)
现在,有了这些,我想把它映射到
User_View: {firstName, lastName, city, state}.
Run Code Online (Sandbox Code Playgroud)
其中,first_name和last_name来自User对象,来自Address对象的city&state.
现在,我的问题是,怎么做?
但是,目前,我这样做
@Mapper
public abstract class UserViewMapper {
@Mappings({
@Mapping(source = "first_name", target = "firstName"),
@Mapping(source = "last_name", target = "lastName"),
@Mapping(target = "city", ignore = true),
@Mapping(target = "state", ignore = true)
})
public abstract UserView userToView(User user);
public UserView addressToView(UserView userView, Address address) {
if (userView == null) {
return null;
}
if (address == null) …Run Code Online (Sandbox Code Playgroud) 这是我的上下文:我使用byteBuddy动态生成一个类,该类根据外部配置将对象转换为另一个对象.我遇到了一些问题,我想找到另一种方法,就是我发现MapStruct的方法.
所以我尝试构建简单的映射器,我想知道是否有可能自定义注释以添加转换函数.比如我想:
@Mapping(
source = "mySourceField",
sourceType = "String",
target = "myTargetField",
targetType = "Integer",
transformation = {"toInteger", "toSquare"}
),
Run Code Online (Sandbox Code Playgroud)
在mapper实现上我会有类似的东西:
public TypeDest toSiteCatTag(TypeSrc obj) {
if ( obj == null ) {
return null;
}
TypeDest objDest = new TypeDest();
objDest.myTargetField = Formatter.toSquare(
Formatter.toInteger(obj.mySourceField));
return objDest;
}
Run Code Online (Sandbox Code Playgroud)
如果有人能帮助我实现这一目标,我将不胜感激,这将为我节省大量时间.
提前致谢.