java .lang.StackOverflowError (Cycli c Reference) с JPA и Mapstruct - PullRequest
0 голосов
/ 12 февраля 2020

Я новичок в mapstruct. Я пытаюсь сопоставить объект Entity (двунаправленный) с объектом DTO, используя Mapstruct. Я могу получить объект сущности, используя репозиторий JPA, и когда я пытаюсь сопоставить его с объектом DTo, я получаю java .lang.StackOverflowError.

Код:

@Entity
@Table(name = "product_category")
@Getter
@Setter
@ToString(exclude = {"products"}) 

public class ProductCategory extends BaseModel<String> {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FARM_PRODUCT_CATEGORY_GENERATOR")
    @SequenceGenerator(name = "FARM_PRODUCT_CATEGORY_GENERATOR", sequenceName = "FARM_PRODUCT_CATEGORY_GENERATOR_SEQ", allocationSize = 1)
    @Column(name = "farm_product_category_id")
    public Long productCategoryId;

    @Column(name="category_name")
    public String categoryName;

    @OneToMany(mappedBy = "productCategory", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    public List<FarmProducts> products;

}

@Entity
@Table(name="farm_products")
@Getter
@Setter
@ToString(exclude= "productCategory")
public class FarmProducts extends BaseModel<String> {
    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "FARM_PRODUCT_GENERATOR")
    @SequenceGenerator(name = "FARM_PRODUCT_GENERATOR", sequenceName = "FARM_PRODUCT_GENERATOR_SEQ", allocationSize = 1)
    @Column(name = "farm_product_id")
    public Long productId;

    @ManyToOne
    @JoinColumn(name = "farm_product_category_id")
    public ProductCategory productCategory;

    @Column(name = "product_name")
    public String product;

    @Column(name = "is_deleted")
    public String isDeleted;

}
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseModel<U> {

    @CreatedBy
    protected U createdBy;

    @CreatedDate
    @Temporal(TemporalType.TIMESTAMP)
    protected Date creationDate;

    @LastModifiedBy
    protected U lastModifiedBy;

    @LastModifiedDate
    @Temporal(TemporalType.TIMESTAMP)
    protected Date lastModifiedDate;

}

Класс DTO:

@Data
public class AuditDTO implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = -775795624442449273L;

    public String createdBy;

    public Date creationDate;

    public Date lastModifiedBy;

    public Date lastModifiedDate;


}

@Data
public class FarmProductCategoryDTO extends AuditDTO implements Serializable{

    /**
     * 
     */
    private static final long serialVersionUID = 7016941232710915827L;


    public Long productCategoryId;

    public List<FarmProductDTO> products;


}

@Data
public class FarmProductDTO extends AuditDTO implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 6164359760527049606L;

    public Long productId;

    public FarmProductCategoryDTO farmProductCategoryVO;

    public String product;

    public String isDeleted;



}

Класс репозитория:

@Repository
public interface FarmProductCategoryRepository  extends JpaRepository<ProductCategory, Long>{

    List<ProductCategory> findAll();

}

Класс обслуживания:

@Service
public class FarmProductServiceImpl implements FarmProductService {

    @Autowired
    FarmProductCategoryRepository farmProductRepository;

    @Autowired
    ProductCategoryMapper productCategoryMapper;


    /**
     * 
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, readOnly = true)
    public List<FarmProductCategoryDTO> farmProductList() {
        List<FarmProductCategoryDTO>  farmCategories = null;
         List<ProductCategory> productCategory = farmProductRepository.findAll();
         System.out.println("farmProduct"+productCategory.size());

         farmCategories = productCategoryMapper.productCategoryToProductCategoryDTO(productCategory);

        return farmCategories;
    }
}

Класс картографа:

@Mapper(componentModel = "spring",uses=ProductMapper.class)
public interface ProductCategoryMapper {
    @Mapping(source = "products", target = "products")
    FarmProductCategoryDTO productCategoryToProductCategoryDTO(ProductCategory productCategory);

    List<FarmProductCategoryDTO> productCategoryToProductCategoryDTO(List<ProductCategory> productCategory);

    ProductCategory FarmProductCategoryDTOToProductCategory(FarmProductCategoryDTO farmProductCategoryDTO);
}

@Mapper(componentModel="spring")

public interface ProductMapper  {

    /*
     * @Mappings({
     * 
     * @Mapping(source="productCategory",target = "farmProductCategoryVO",
     * ignore=true),
     * 
     * })
     */


     FarmProductDTO farmProductToProductDto(FarmProducts farmProducts);

     List<FarmProductDTO> farmProductsToFarmProductsDtos(List<FarmProducts> callRecords);


}

У меня есть двунаправленное отображение.

При попытке получить все категории из БД работает нормально. и когда я пытаюсь сопоставить то же самое с DTO для объекта, используя mapstruct, я получаю ошибку ниже.

java.lang.StackOverflowError
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductsToFarmProductsDtos(ProductMapperImpl.java:42)
at com.company.farmer.mapper.dto.ProductMapperImpl.productCategoryToFarmProductCategoryDTO(ProductMapperImpl.java:58)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductToProductDto(ProductMapperImpl.java:29)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductsToFarmProductsDtos(ProductMapperImpl.java:44)
at com.company.farmer.mapper.dto.ProductMapperImpl.productCategoryToFarmProductCategoryDTO(ProductMapperImpl.java:58)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductToProductDto(ProductMapperImpl.java:29)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductsToFarmProductsDtos(ProductMapperImpl.java:44)
at com.company.farmer.mapper.dto.ProductMapperImpl.productCategoryToFarmProductCategoryDTO(ProductMapperImpl.java:58)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductToProductDto(ProductMapperImpl.java:29)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductsToFarmProductsDtos(ProductMapperImpl.java:44)
at com.company.farmer.mapper.dto.ProductMapperImpl.productCategoryToFarmProductCategoryDTO(ProductMapperImpl.java:58)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductToProductDto(ProductMapperImpl.java:29)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductsToFarmProductsDtos(ProductMapperImpl.java:44)
at com.company.farmer.mapper.dto.ProductMapperImpl.productCategoryToFarmProductCategoryDTO(ProductMapperImpl.java:58)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductToProductDto(ProductMapperImpl.java:29)
at com.company.farmer.mapper.dto.ProductMapperImpl.farmProductsToFarmProductsDtos(ProductMapperImpl.java:44)

1 Ответ

2 голосов
/ 15 февраля 2020

При отображении с циклами вам придется как-то разбить этот цикл:

Использование @ Context

Взгляните на пример mapstruct-mapping-with-циклы .

Игнорировать на каком-то уровне

Как в вашем закомментированном коде.

@Mapper
public interface ProductMapper  {

    @Mapping(source="productCategory",target = "farmProductCategoryVO", ignore=true)
    FarmProductDTO farmProductToProductDto(FarmProducts farmProducts);

    List<FarmProductDTO> farmProductsToFarmProductsDtos(List<FarmProducts> callRecords);
}
...