【问题标题】:How to write custom findAll() with Specification in JPA repository如何在 JPA 存储库中使用规范编写自定义 findAll()
【发布时间】:2020-08-10 00:58:06
【问题描述】:

当我使用 skuRepository.getAll() 时,它可以正常工作,但是当我应用在规范中定义的过滤器时 (List filteredRegs = skuRepository.getAll(specification)) 我仍然得到表的所有行 我应该怎么做才能将规范应用于我的自定义方法?

public interface SkuRepository extends CrudRepository<Sku, Integer>, JpaSpecificationExecutor<Sku> {

    @Query("select s from Sku s join fetch s.unit un join fetch s.supplier sup WHERE un.id = sku_unit_id AND sup.id = supplier_id")
    List<Sku> getAll(@Nullable Specification<Sku> var1);

    @Query("select s from Sku s join fetch s.unit un join fetch s.supplier sup WHERE un.id = sku_unit_id AND sup.id = supplier_id")
    List<Sku> getAll();
}

更新: 这是我的实体。 当我使用 Specification API 按 Sku 表进行抽样时,我在日志中看到三个单独的选择:一个用于 Sku 实体,一个用于单元,一个用于供应商。我希望我的应用程序通过连接进行选择。 我读到这是由于我使用 EAGER 提取类型,所以我将其更改为 LAZY,但后来我遇到了另一个问题:“InvalidDefinitionException: No serializer found...”这是合乎逻辑的,因为相关实体 Unit 和 Supplier 是未加载。 然后我决定用请求编写我的自定义 getAll():

@Query("select s from Sku s join fetch s.unit un join fetch s.supplier sup WHERE un.id = sku_unit_id AND sup.id = supplier_id ORDER BY s.name")

但现在它不支持规范。 请告知该怎么做。

@Entity
@Table(name = "sku")
public class Sku implements Cloneable, CloneableEntity {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "sku_code", length = 6, nullable = false, unique = true)
    private String code;

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

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "sku_unit_id", nullable = false)
    private Unit unit;

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)
    @JoinColumn(name = "supplier_id", nullable = false)
    private Supplier supplier;

    @Column(name = "qty_in_sec_pkg")
    private int quantityInSecondaryPackaging;

    @Column(name = "sku_is_active", nullable = false)
    private boolean isActive;

//constructors, getters, setters

}

@Entity
@Table(name = "units")
public class Unit {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id ")
    private int id;

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

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

//constructors, getters, setters
}

@Entity
@Table(name = "suppliers")
public class Supplier {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id ")
    private int id;

    @Column(name = "supplier_code", length = 6, nullable = false, unique = true)
    private String supplierCode;

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

    @Column(name = "create_date", length = 19, nullable = false)
    private String createDate;

    @Column(name = "update_date", length = 19)
    private String updateDate;
//constructors, getters, setters
}

【问题讨论】:

    标签: spring jpa criteria


    【解决方案1】:

    你不能混合@Query 和 Specification

    你只能使用JpaSpecificationExecutor接口方法来使用规范。

    了解更多详情here

    【讨论】:

    • 它已经实现了。我想避免 N+1 问题,这就是我实现自定义方法的原因。另一种方法是什么?
    • 您也可以对子字段条件使用规范。其他方式可以避免N+1问题。
    • 你能举一些例子吗?我需要对所有字段使用规范,而不仅仅是孩子。
    • 首先我需要知道您在哪种情况下遇到问题,然后我才能正确解决它。 N+1 是一个问题,不是正常情况,可能由于我们的错误实现而出现
    • 是的,您可以在所有有问题的字段中使用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 2021-10-13
    • 2021-12-18
    • 1970-01-01
    • 2018-06-15
    • 2014-09-08
    • 1970-01-01
    相关资源
    最近更新 更多