mapstruct – 目标载荷是子类,无需转换为真实类型?

huangapple go评论64阅读模式
英文:

mapstruct - target payload is subclass, no cast to real type?

问题

使用mapstruct时,我们有以下(示例)场景:

我们的目标类“Zoo”保存了对“Animal”的一些引用。动物可以是“Lion”或“Elephant”。现在我们想要根据某个源类“ZooMaker”的属性设置狮子的teethLength或大象的trunk length。

class Zoo {
 Animal animal;
...
class Animal {
 long size;
...
class Lion extends Animal {
 long teethLength;
...
class Elephant extends Animal{
 long trunkLength;
...
class ZooMaker {
String animal;
long length;

我们想要做的是使用mapstruct动态创建Zoo中的Animal。但是,如果我们使用一个工厂类

public class PayloadFactory {

	public Animal createAnimal() {
      return new Lion();	
    }
}

对于这个Mapper类:

@Mapper
public abstract class AnimalMapper {

	@Mapping(target = "animal.teethLength", source = "length")
	public abstract Zoo toZoo(ZooMaker zooMaker);
...

我们会得到一个错误,类似于:
错误:(10, 9)java:在类型Animal中,目标名称为“animal.teethLength”的属性未知。“Did you mean "animal.size"?”

即使将Lion用作工厂的返回类型,或者使用ObjectFactory,如:

@ObjectFactory
	public Lion createLion() {
		return new Lion();
	}

也会导致相同的问题?有任何解决这种类型转换问题的想法吗?

英文:

While using mapstruct we've got the following (sample) scenario:

Our target class "Zoo" holds some reference of "Animal". An animal can be a "Lion" or an "Elephant". Now we want to set the lion's teethLength or the elephant's trunk lenght depending on some source class's ("ZooMaker") property.

class Zoo {
 Animal animal;
...
class Animal {
 long size;
...
class Lion extends Animal {
 long teethLength;
...
class Elephant extends Animal{
 long trunkLength;
...
class ZooMaker {
String animal;
long lenght;

What we wanna do is to create the Animal in Zoo dynamically using mapstruct. But, if we use a FactoryClass

public class PayloadFactory {

	public Animal createAnimal() {
      return new Lion();	
    }
}

for this Mapper class:

@Mapper
public abstract class AnimalMapper {

	@Mapping(target = "animal.teethLength", source = "length")
	public abstract Zoo toZoo(ZooMaker zooMaker);
...

we get an error like:
Error:(10, 9) java: Unknown property "teethLength" in type Animal for target name "animal.teethLength". Did you mean "animal.size"?

Even using Lion as Factory's return type or using an ObjectFactory like

@ObjectFactory
	public Lion createLion() {
		return new Lion();
	}

causes the same problem? Any ideas how to solve that type conversion issue?

答案1

得分: 1

MapStruct是一个注解处理器。这意味着它只使用在编译时可用的信息,而不是运行时。

在你的示例中,Zoo有一个类型为Animal的属性animal,所以MapStruct只能在编译时映射到关于Animal已知的属性。你需要做一些其他操作来映射特定类型的属性。

你可以使用@AfterMapping,在那里你可以进行instanceOf检查等操作。

英文:

MapStruct is an annotation processor. This means that it uses only information available at compile time and not runtime.

In your example Zoo has the property animal of type Animal, so MapStruct can only map to properties known about Animal during compilation time. You'll have to do something else to map the type specific properties.

You can use @AfterMapping where you can do instanceOf checks, etc.

huangapple
  • 本文由 发表于 2020年9月28日 17:53:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/64099889.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定