@EntityGraph с несколькими "attributePaths" или @NamedEntityGraph с несколькими "attributeNodes" не работает - PullRequest
0 голосов
/ 01 августа 2020

У меня есть класс Продукт:

@NamedEntityGraph(
        name = "product-excel-entity-graph",
        attributeNodes = {
                @NamedAttributeNode(value = "productCategoryList", subgraph = "categories"),
                @NamedAttributeNode(value = "productImageList", subgraph = "images")
        }
        ,
        subgraphs = {
                @NamedSubgraph(name = "categories", attributeNodes = {@NamedAttributeNode("category")}),
                @NamedSubgraph(name = "images", attributeNodes = {@NamedAttributeNode("image")})
        }
)
public class Product {

    @Id
    @GeneratedValue(generator = "product_seq", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(sequenceName = "product_id_seq", name = "product_seq", allocationSize = 1)
    private Long id;

    @Column(name = "name")
    private String name;

    @OneToMany(mappedBy = "product")
    @JsonIgnore
    private List<CategoryProduct> productCategoryList;

    @OneToMany(mappedBy = "product")
    @JsonIgnore
    private List<ProductImage> productImageList;

}

Класс Категория Продукт:

@Entity
@Table(name = "category_product")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CategoryProduct {
    @Id
    @GeneratedValue(generator = "category_product_seq", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(sequenceName = "category_product_id_seq", name = "category_product_seq", allocationSize = 1)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "product_id", foreignKey = @ForeignKey(name = "category_product_product_fk"), nullable = false)
    private Product product;

    @ManyToOne
    @JoinColumn(name = "category_id", foreignKey = @ForeignKey(name = "category_product_category_fk"), nullable = false)
    private Category category;
}

Категория класса:

@Entity
@Table(name = "category")
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString(exclude = {"categoryProductList"})
public class Category {
    @Id
    @GeneratedValue(generator = "category_seq", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(sequenceName = "category_id_seq", name = "category_seq", allocationSize = 1)
    private Long id;

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

    @OneToMany(mappedBy = "category", fetch = FetchType.LAZY)
    @JsonIgnore
    private List<CategoryProduct> categoryProductList;
}

Класс Изображение продукта:

@Entity
@Table(name = "product_image")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ProductImage {
    @Id
    @GeneratedValue(generator = "product_image_seq", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(sequenceName = "product_image_id_seq", name = "product_image_seq", allocationSize = 1)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "product_id", foreignKey = @ForeignKey(name = "product_image_product_fk"), nullable = false)
    private Product product;

    @ManyToOne
    @JoinColumn(name = "image_id", foreignKey = @ForeignKey(name = "product_image_image_fk"), nullable = false)
    private Image image;
}

Образ класса:

@Entity
@Table(name = "image")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Image {
    @Id
    @GeneratedValue(generator = "image_seq", strategy = GenerationType.SEQUENCE)
    @SequenceGenerator(sequenceName = "image_id_seq", name = "image_seq", allocationSize = 1)
    private Long id;

    @Column(name = "img_url")
    private String imgUrl;
}

В ProductRepo у меня есть следующий метод:

@Repository
public interface ProductRepo extends JpaRepository<Product, Long> {

    @EntityGraph(value = "product-excel-entity-graph")
    List<Product> findAllByIdNotNull();
}

В ProductServiceImpl следующий метод:

@Service
public class ProductServiceImpl implements ProductService {

    private final ProductRepo productRepo;
    private final CategoryRepo categoryRepo;
    private final CategoryProductRepo categoryProductRepo;
    private final ImageRepo imageRepo;
    private final ProductImageRepo productImageRepo;

    @Autowired
    public ProductServiceImpl(ProductRepo productRepo,
                              CategoryRepo categoryRepo,
                              CategoryProductRepo categoryProductRepo,
                              ImageRepo imageRepo,
                              ProductImageRepo productImageRepo) {
        this.productRepo = productRepo;
        this.categoryRepo = categoryRepo;
        this.categoryProductRepo = categoryProductRepo;
        this.imageRepo = imageRepo;
        this.productImageRepo = productImageRepo;
    }

    @Override
    public List<Product> getAllProducts() throws Exception {
        try{
            List<Product> products = productRepo.findAllByIdNotNull();
            if (products.isEmpty()) {
                throw new Exception("NO PRODUCT");
            }
            return products;
        } catch (Throwable t){
            throw new Exception(t.getMessage());
        }
    }
}

Проблема в том, когда я Я пытаюсь получить строки через productService.getAllProducts () , запрос возвращает статус 400. После того, как я переместил вызов метода репо в try-catch, теперь он просто показывает исключение NullPointerException. Но это работает, когда я использую "attributeNodes" с одним значением, таким же, как код ниже:

@NamedEntityGraph(
        name = "product-excel-entity-graph",
        attributeNodes = @NamedAttributeNode(value = "productCategoryList", subgraph = "categories"),
        subgraphs = @NamedSubgraph(name = "categories", attributeNodes = {@NamedAttributeNode("category")})
)

или:

@NamedEntityGraph(
        name = "product-excel-entity-graph",
        attributeNodes = @NamedAttributeNode(value = "productImageList", subgraph = "images"),
        subgraphs = @NamedSubgraph(name = "images", attributeNodes = {@NamedAttributeNode("image")})
)

Та же проблема и с @EntityGraph. Он не работает с несколькими значениями, как в коде ниже:

@EntityGraph(attributePaths = {"productCategoryList", "productImageList"})
    List<Product> findAll();

, но работает с одним значением:

@EntityGraph(attributePaths = {"productCategoryList"})
    List<Product> findAll();

и

@EntityGraph(attributePaths = {"productImageList"})
    List<Product> findAll();

Как это исправить ?

...