我们正在使用不可变框架来生成所有的DTO。现在我们想用MapStruct将这些对象映射到另一个对象。但是生成的DTO是不可变的,没有设置器和构造器,对应于构建器模式。它们只通过静态builder()
-方法访问的相应生成器来填充。
相反,我们尝试将DTO1映射到DTO2.Builder,如果mapstruct能够识别生成器中的setter,那么它就可以工作,但是它们没有void返回类型,而是返回生成器本身,以便进行流畅的连接。
@Value.Immutable
public interface MammalDto {
public Integer getNumberOfLegs();
public Long getNumberOfStomachs();
}
和
@Value.Immutable
public interface MammalEntity {
public Long getNumberOfLegs();
public Long getNumberOfStomachs();
}
然后我们有了MapStruct的映射器接口:
@Mapper(uses = ObjectFactory.class)
public interface SourceTargetMapper {
SourceTargetMapper MAPPER = Mappers.getMapper( SourceTargetMapper.class );
ImmutableMammalEntity.Builder toTarget(MammalDto source);
}
为了让mapstruct找到构建器,我们需要一个工厂:
public class ObjectFactory {
public ImmutableMammalDto.Builder createMammalDto() {
return ImmutableMammalDto.builder();
}
public ImmutableMammalEntity.Builder createMammalEntity() {
return ImmutableMammalEntity.builder();
}
}
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.immutables</groupId>
<artifactId>value</artifactId>
<version>2.2.8</version>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.2.0.Beta3</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
@Test
public void test() {
MammalDto s = ImmutableMammalDto.builder().numberOfLegs(4).numberOfStomachs(3l).build();
MammalEntity t = SourceTargetMapper.MAPPER.toTarget(s).build();
assertThat(t.getNumberOfLegs()).isEqualTo(4);
assertThat(t.getNumberOfStomachs()).isEqualTo(3);
}
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
//...
)
public class SourceTargetMapperImpl implements SourceTargetMapper {
private final ObjectFactory objectFactory = new ObjectFactory();
@Override
public Builder toTarget(MammalDto source) {
if ( source == null ) {
return null;
}
Builder builder = objectFactory.createMammalEntity();
return builder;
}
}
public final Builder numberOfLegs(Long numberOfLegs) {
this.numberOfLegs = Objects.requireNonNull(numberOfLegs, "numberOfLegs");
return this;
}
有没有办法让mapstruct找到这些设置器?或者是用构建器处理这种不可变对象的更好方法?
编辑:正如我在评论中所说,我遇到了问题#782。在版本1.2.0.beta3中,构建器仍然不受支持。但是有几个关于这个主题的讨论,所以如果一个人有同样的问题,关注这个问题可能会很有趣。
因为1.3MapStruct支持不可变。更多细节请看这里。
问题内容: 我正在努力使可变对象与不可变对象有关。使用可变对象会带来很多负面影响(例如,从方法中返回字符串数组),但是我很难理解它的负面影响。使用可变对象的最佳实践是什么?您是否应尽可能避免使用它们? 问题答案: 好吧,这有几个方面。 没有参考身份的可变对象会在奇数时间导致错误。例如,考虑使用基于值的方法的 : 当实例用作键时,实例在映射中“丢失”,因为实例和相等性基于可变值。这些值在映射之外更改
我的目标是让Java对象不可变。我有一个班级< code >学生。为了实现不变性,我用以下方式对它进行了编码: 我的问题是,实现班级不变性的最佳方法是什么?
我有一个不可变对象,它是使用组件映射的Hibernate持久化对象的成员。例如,对应于一个表,该表的字段类型为immutable: 在我的: 这不起作用,因为在运行时HiberNate抱怨没有和的设置器。有没有办法使用不可变对象作为HiberNate持久对象的组件? 跟进:我没有使用注释,而是使用。和都不是。
我正在使用JAXB从XSD文件创建Java对象。我正在创建不可变包装器来隐藏由JAXB生成的对象(之前我更新了JAXB对象,以实现不可变接口并将接口返回给客户机。但意识到改变自动生成的类是不好的,因此使用包装器) 目前,我正在将这些不可变的包装返回到客户端应用程序。是否有任何选项,使自动生成的类将是不可变的,并避免创建不可变包装器的额外工作。任何其他方法都是鼓励的。 谢谢
由于这是一个热门的话题,这些天,我无法理解某些概念。请原谅,如果我听起来很愚蠢,但当我试图创建不可变对象时,我发现大多数帖子如下 null null 此测试用例失败并打印Cassandra。 如果我做错了什么让我知道。
提前谢了。