Как использовать ModelMapper для объектов с глубоким наследованием?

A.java

@Entity
@Getter
@Setter
@Inheritance
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, inclue=JsonTypeInfo.As.PROPERTY, property="type") 
@JsonSubTypes({
    @JsonSubTypes.Type(value=AA.class,name="aa"),
    @JsonSubTypes.Type(value=AB.class,name="ab"),
})
public abstract class A {
    @Id
    @GeneratedValue
    private Long id;

    //json ignore for getter
    @ManyToOne
    private A parent;

    @OneToMany(mappedBy="parent")
    private List<A> children;
}

AA.java

@Entity
@Getter
@Setter
@DiscriminatorValue("aa")
public class AA extends A{
    private User user;
}

AB.java

@Entity
@Getter
@Setter
@DiscriminatorValue("ab")
public class AB extends A {
    private String name;
}

Теперь, когда я возвращаю экземпляр класса AB как JSON, он выглядит так:

{
     "id": 1,
     "type": "ab",
     "children": [...],
     "name": "ali"
}

Поскольку я хочу использовать пользовательский User JSON, я хочу использовать ModelMapper. Все вещи "ОК", кроме "Отсутствие type.

Мои DTO:

@Getter
@Setter
public class ADto {
     private Long id;

     private List<ADto> children;
}

@Getter
@Setter
public class AADto extends ADto {
     private UserDto user;
}

@Getter
@Setter
public class ABDto extends ADto {
     private String name;
}

Как я могу использовать ModelMapper и получить type класса?

Ответ 1

Возможные решения:

  1. Вы пытались добавить тип атрибута в родительский класс? Этого должно быть достаточно, если вы извлекаете это поле из БД.
  2. Простой проверенный трюк, добавьте protected String type = this.getClass().getSimpleName().toLowerCase(); , Обратите внимание, что он должен быть защищен. Здесь мой проверенный код:

    @Data
    abstract class A {
      protected String type = this.getClass().getSimpleName().toLowerCase();
    }
    
     class AB extends A {}
    
     class AA extends A {}
    
     @Test
     public void test(){
        A a1 = new AB();
        A a2 = new AA();
        assertThat(a1.getType()).isEqualTo("ab");
        assertThat(a2.getType()).isEqualTo("aa");
     }