将 Mapstruct 升级到 1.4。2.Final
Upgrade Mapstruct to 1.4.2.Final
我正在将项目 mapstruct 依赖项从 1.2.0.Final 升级到 1.4.2.Final。
一切顺利,util 落在一个复杂的映射器上,它看起来像下面的代码片段:
@Mapper(componentModel = "spring")
public abstract class CustomMapper{
@Named("mapTestla")
@Mapping(target = "f", source = "t.f")
public abstract TestlaDTO mapTestla(Testla t) {}
@Named("mapBar")
@Mapping(target = "t", source = "b.t", qualifiedByName = "mapTestla")
public abstract BarDTO mapBar(Bar b) {}
@Mappings({@Mapping(target = "a", source = "f.a"),
@Mapping(target = "b", source = "f.b", qualifiedByName = "mapBar")})
public abstract FooDTO mapFoo(Foo f) {}
}
class Foo {
String a;
Bar b;
}
class Bar {
Tesla t;
}
class Testla {
String f;
}
class FooDTO {
String a;
Bar b;
}
class BarDTO {
TeslaDTO t;
}
class TestlaDTO {
String f;
}
正如您在错误中看到的那样,mapstruct 没有检测到引用的方法,尽管它们被注释为 @Named
。看起来像是 spring aop proxy 问题..
知道这个问题吗?
PS: 我不想将映射器分成多个映射器,因为我们 运行 落后于计划,这可能会导致影响.
错误得到:
错误:限定符错误。找不到使用@Named#value: [ mapBar] 注释的方法。有关详细信息,请参阅 https://mapstruct.org/faq/#qualifier。
错误:限定符错误。没有找到用@Named#value: [ mapTestla] 注释的方法。有关详细信息,请参阅 https://mapstruct.org/faq/#qualifier。
您似乎从不同于 MapStruct 的库中导入了不正确的 @Named
注释。
您的示例在 MapStruct 1.4 中运行良好。2.Final。
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
@Mapper(componentModel = "spring")
public abstract class CustomMapper{
@Named("mapTestla")
@Mapping(target = "f", source = "t.f")
public abstract TestlaDTO mapTestla(Testla t);
@Named("mapBar")
@Mapping(target = "t", source = "b.t", qualifiedByName = "mapTestla")
public abstract BarDTO mapBar(Bar b);
@Mappings({@Mapping(target = "a", source = "f.a"),
@Mapping(target = "b", source = "f.b", qualifiedByName = "mapBar")})
public abstract FooDTO mapFoo(Foo f) ;
}
生成的代码:
@Component
public class CustomMapperImpl extends CustomMapper {
@Override
public TestlaDTO mapTestla(Testla t) {
if ( t == null ) {
return null;
}
TestlaDTO testlaDTO = new TestlaDTO();
testlaDTO.f = t.f;
return testlaDTO;
}
@Override
public BarDTO mapBar(Bar b) {
if ( b == null ) {
return null;
}
BarDTO barDTO = new BarDTO();
barDTO.t = mapTestla( b.t );
return barDTO;
}
@Override
public FooDTO mapFoo(Foo f) {
if ( f == null ) {
return null;
}
FooDTO fooDTO = new FooDTO();
fooDTO.a = f.a;
fooDTO.b = mapBar( f.b );
return fooDTO;
}
}
根据文档:Mapping object references。
您不需要通过方法限定符显式指定内部对象映射。为所有对象指定映射方法就足够了。 MapStract 将自动对它们进行限定。
@Mapper(componentModel = "spring")
public abstract class CustomMapper {
public abstract TestlaDTO mapTestla(Testla t);
public abstract BarDTO mapBar(Bar b);
public abstract FooDTO mapFoo(Foo f) ;
}
生成的代码:
@Component
public class CustomMapperImpl extends CustomMapper {
@Override
public TestlaDTO mapTestla(Testla t) {
if ( t == null ) {
return null;
}
TestlaDTO testlaDTO = new TestlaDTO();
testlaDTO.f = t.f;
return testlaDTO;
}
@Override
public BarDTO mapBar(Bar b) {
if ( b == null ) {
return null;
}
BarDTO barDTO = new BarDTO();
barDTO.t = mapTestla( b.t );
return barDTO;
}
@Override
public FooDTO mapFoo(Foo f) {
if ( f == null ) {
return null;
}
FooDTO fooDTO = new FooDTO();
fooDTO.a = f.a;
fooDTO.b = mapBar( f.b );
return fooDTO;
}
}
如您所见,MapStruct 生成了相同的映射器代码,但没有附加注释!
我正在将项目 mapstruct 依赖项从 1.2.0.Final 升级到 1.4.2.Final。 一切顺利,util 落在一个复杂的映射器上,它看起来像下面的代码片段:
@Mapper(componentModel = "spring")
public abstract class CustomMapper{
@Named("mapTestla")
@Mapping(target = "f", source = "t.f")
public abstract TestlaDTO mapTestla(Testla t) {}
@Named("mapBar")
@Mapping(target = "t", source = "b.t", qualifiedByName = "mapTestla")
public abstract BarDTO mapBar(Bar b) {}
@Mappings({@Mapping(target = "a", source = "f.a"),
@Mapping(target = "b", source = "f.b", qualifiedByName = "mapBar")})
public abstract FooDTO mapFoo(Foo f) {}
}
class Foo {
String a;
Bar b;
}
class Bar {
Tesla t;
}
class Testla {
String f;
}
class FooDTO {
String a;
Bar b;
}
class BarDTO {
TeslaDTO t;
}
class TestlaDTO {
String f;
}
正如您在错误中看到的那样,mapstruct 没有检测到引用的方法,尽管它们被注释为 @Named
。看起来像是 spring aop proxy 问题..
知道这个问题吗?
PS: 我不想将映射器分成多个映射器,因为我们 运行 落后于计划,这可能会导致影响.
错误得到:
错误:限定符错误。找不到使用@Named#value: [ mapBar] 注释的方法。有关详细信息,请参阅 https://mapstruct.org/faq/#qualifier。
错误:限定符错误。没有找到用@Named#value: [ mapTestla] 注释的方法。有关详细信息,请参阅 https://mapstruct.org/faq/#qualifier。
您似乎从不同于 MapStruct 的库中导入了不正确的 @Named
注释。
您的示例在 MapStruct 1.4 中运行良好。2.Final。
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.Named;
@Mapper(componentModel = "spring")
public abstract class CustomMapper{
@Named("mapTestla")
@Mapping(target = "f", source = "t.f")
public abstract TestlaDTO mapTestla(Testla t);
@Named("mapBar")
@Mapping(target = "t", source = "b.t", qualifiedByName = "mapTestla")
public abstract BarDTO mapBar(Bar b);
@Mappings({@Mapping(target = "a", source = "f.a"),
@Mapping(target = "b", source = "f.b", qualifiedByName = "mapBar")})
public abstract FooDTO mapFoo(Foo f) ;
}
生成的代码:
@Component
public class CustomMapperImpl extends CustomMapper {
@Override
public TestlaDTO mapTestla(Testla t) {
if ( t == null ) {
return null;
}
TestlaDTO testlaDTO = new TestlaDTO();
testlaDTO.f = t.f;
return testlaDTO;
}
@Override
public BarDTO mapBar(Bar b) {
if ( b == null ) {
return null;
}
BarDTO barDTO = new BarDTO();
barDTO.t = mapTestla( b.t );
return barDTO;
}
@Override
public FooDTO mapFoo(Foo f) {
if ( f == null ) {
return null;
}
FooDTO fooDTO = new FooDTO();
fooDTO.a = f.a;
fooDTO.b = mapBar( f.b );
return fooDTO;
}
}
根据文档:Mapping object references。
您不需要通过方法限定符显式指定内部对象映射。为所有对象指定映射方法就足够了。 MapStract 将自动对它们进行限定。
@Mapper(componentModel = "spring")
public abstract class CustomMapper {
public abstract TestlaDTO mapTestla(Testla t);
public abstract BarDTO mapBar(Bar b);
public abstract FooDTO mapFoo(Foo f) ;
}
生成的代码:
@Component
public class CustomMapperImpl extends CustomMapper {
@Override
public TestlaDTO mapTestla(Testla t) {
if ( t == null ) {
return null;
}
TestlaDTO testlaDTO = new TestlaDTO();
testlaDTO.f = t.f;
return testlaDTO;
}
@Override
public BarDTO mapBar(Bar b) {
if ( b == null ) {
return null;
}
BarDTO barDTO = new BarDTO();
barDTO.t = mapTestla( b.t );
return barDTO;
}
@Override
public FooDTO mapFoo(Foo f) {
if ( f == null ) {
return null;
}
FooDTO fooDTO = new FooDTO();
fooDTO.a = f.a;
fooDTO.b = mapBar( f.b );
return fooDTO;
}
}
如您所见,MapStruct 生成了相同的映射器代码,但没有附加注释!