5

I'm using mapstruct to map my entity and dto classes... I'm having problem with a loop on my mapper class...

I have no ideia what to do... This is my mapper classes

    @Mapper(componentModel = "spring", uses = {BrandMapper.class})
public interface VehicleTypeMapper {

    VehicleTypeDTO vehicleTypetoVehicleTypeDTO(VehicleType vehicleType);

    Iterable<VehicleTypeDTO> vehicleTypetoVehicleTypeDTO(Iterable<VehicleType> vehicleTypes);

    VehicleType vehicleTypeDTOtoVehicleType(VehicleTypeDTO vehicleTypeDTO);
}

    @Mapper(componentModel = "spring", uses = { VehicleTypeMapper.class, ModelMapper.class })
public interface BrandMapper {

    BrandDTO brandtoBrandDTO(Brand brand);

    Iterable<BrandDTO> brandtoBrandDTO(Iterable<Brand> brands);

    Brand brandDTOtoBrand(BrandDTO brandDTO);
}

My entity classes... DTO is the same attributes as my entity classes...

@Entity
@Table(name = "tb_brand")
public class Brand implements Serializable {

    private static final long serialVersionUID = 1506494747401320985L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "vehicle_type_id", foreignKey = @ForeignKey(name = "fk_vehicle_type"))
    private VehicleType vehicleType;

    @JsonIgnore
    @OneToMany(mappedBy = "brand", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Model> models;

    @Column(name = "description", nullable = false)
    private String description;

//GETS AND SETS
}

@Entity
@Table(name = "tb_vehicle_type")
public class VehicleType {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", nullable = false)
    private Long id;

    @JsonIgnore
    @OneToMany(mappedBy = "vehicleType", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private List<Brand> brands;

    @Column(name = "description", nullable = false)
    private String description;

//GETS AND SETS
}

THE STACK TRACE

at br.com.meuveiculocerto.business.mapper.VehicleTypeMapperImpl.brandListToBrandDTOList(VehicleTypeMapperImpl.java:81) ~[classes/:na]
at br.com.meuveiculocerto.business.mapper.VehicleTypeMapperImpl.vehicleTypetoVehicleTypeDTO(VehicleTypeMapperImpl.java:33) ~[classes/:na]
at br.com.meuveiculocerto.business.mapper.BrandMapperImpl.brandtoBrandDTO(BrandMapperImpl.java:35) ~[classes/:na]
at br.com.meuveiculocerto.business.mapper.VehicleTypeMapperImpl.brandListToBrandDTOList(VehicleTypeMapperImpl.java:81) ~[classes/:na]

Can someone help me to identify why it's looping?

1
  • in my case I had put the mapstruct interface to use itself. Commented Feb 6, 2020 at 19:42

1 Answer 1

10

You have a cyclic dependency between VehicleType and Brand. You have 3 possibilities to resolve the cycles:

  1. One mapper will always ignore the cyclic field. I see that you have @JsonIgnore on the list of Brand in the VehicleType. You could ignore them via Mapping#ignore in your mapper.

  2. You will have explicit mappings that ignore what you don't need and use qualifiers to choose the appropriate methods. More info about qualifiers here in the documentation

  3. Use the latest release of 1.2.0 (at the time of answering 1.2.0.RC1 and use the new @Context parameter. Have a look at the mapping-with-cycles from the mapstruct examples repository. It solves cyclic mapping problems. You don't have to use Object, you can also use your specific types instead.

NOTE: The 1.2.0 release does not offer "out of the box" solving of cyclic mapping, it needs to be done by the users explicitly.

Sign up to request clarification or add additional context in comments.

7 Comments

What the best to use and how i implement? Could you make an example please?
I set @Mapping(target = "brands", ignore = true) and still not work for me, could help?
I've updated my pom project to 1.2.0.RC1 and what the context i need to pass on my repository? @Override public Iterable<VehicleTypeDTO> findAll() { return vehicleTypeMapper.vehicleTypestoVehicleTypeDTOs(vehicleTypeRepository.findAll(), null); } Where its null what i need to pass?
I'm getting this: Unknown property "brands" in result type java.lang.Iterable<br.com.meuveiculocerto.commons.dto.VehicleTypeDTO>. Did you mean "null"? If I add the @mapping property...
I provided you with a link to the mapstruct examples repository that solves exactly this problem. You need to define your own @Context class. There is no such class in MapStruct. I think that the link to the repository with the example is more relevant than writing an example in the answer as the repository can evolve with time and will always be up to date
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.