首页 > 解决方案 > 具有多个“attributePaths”的@EntityGraph 或具有多个“attributeNodes”的@NamedEntityGraph 不起作用

问题描述

我有类产品:

@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 状态。在我将 repo 方法调用移动到 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();

如何解决?

标签: javaspringspring-data-jpaspring-data

解决方案


推荐阅读