Spring Data JPA -延迟加载和@获取(FetchMode.JOIN)

nmpmafwu  于 2022-11-14  发布在  Spring
关注(0)|答案(2)|浏览(168)

2实体ProductMaster和类别

@Entity
@Table(name = "product_master")
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@NamedQuery(name = "ProductMaster.findAll", query = "SELECT p FROM ProductMaster p")
public class ProductMaster implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String description;

//Many Product will have one categoary
    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="category_id")
    private Category category;
    
//get and set fn
}

@Entity
@JsonIgnoreProperties({"hibernateLazyInitializer", "handler"})
@Table(name = "category")
public class Category {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    @JsonIgnore
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "category")
    @Fetch( FetchMode.JOIN)
    private Set<ProductMaster> products = new HashSet<ProductMaster>();

//get and set fn
}

在Product.Join的JPA储存库中执行fetchAll时,预期
休眠模式:选择产品mas0_.id作为标识1_1_,产品mas0_.category_id作为类别11_1_,产品mas0_.created_by作为创建人_2_1_,产品mas0_.created_dt作为创建人_3_1_,产品mas0_.description作为描述4_1_,产品mas0_.image作为图像5_1_,产品mas0_.is_favorite作为is_favor6_1_,产品mas0_.price作为价格7_1_,产品mas0_.title作为标题8_1_,产品mas0_.updated_by作为更新9_1_,产品mas0_.updated_dt作为更新10_1_从产品_主产品mas0_限制?
休眠模式:选择类别0_.id作为id1_0_0_,类别0_.category_name作为类别2_0_0_,类别0_.created_by作为创建日期_3_0_0_,类别0_.created_dt作为创建日期_4_0_0_,类别0_.category_desc作为类别5_0_0_,类别0_.updated_by作为更新日期_6_0_0_,类别0_.updated_dt作为更新日期_7_0_0_,产品1_.category_id作为类别11_1_1_,产品1_.id作为ID1_1_1_,产品1_.id作为ID1_1_2_,产品1_.category_id作为类别11_1_2_,产品1_.created_by作为创建_2_1_2_,产品1_.created_dt作为创建_3_1_2_,产品1_.description作为描述4_1_2_,产品1_.图像如图像5_1_2_,产品1_.是我的最爱如我的最爱6_1_2_,产品1_.价格如价格7_1_2_,产品1_.标题如标题8_1_2_,产品1_.更新者如更新9_1_2_,products1_.updated_dt作为已更新10_1_2_来自类别类别0_左外联接products1_位于类别0_. id =products1_.category_id其中类别0_. id =?
但是当类别JPA存储库中的fetchAll触发了多个产品查询时。

select
    category0_.id as id1_0_,
    category0_.category_name as category2_0_,
    category0_.created_by as created_3_0_,
    category0_.created_dt as created_4_0_,
    category0_.category_desc as category5_0_,
    category0_.updated_by as updated_6_0_,
    category0_.updated_dt as updated_7_0_ 
from
    category category0_ Hibernate: 
select
    products0_.category_id as categor11_1_0_,
    products0_.id as id1_1_0_,
    products0_.id as id1_1_1_,
    products0_.category_id as categor11_1_1_,
    products0_.created_by as created_2_1_1_,
    products0_.created_dt as created_3_1_1_,
    products0_.description as descript4_1_1_,
    products0_.image as image5_1_1_,
    products0_.is_favorite as is_favor6_1_1_,
    products0_.price as price7_1_1_,
    products0_.title as title8_1_1_,
    products0_.updated_by as updated_9_1_1_,
    products0_.updated_dt as updated10_1_1_ 
from
    product_master products0_ 
where
    products0_.category_id=? 2022-09-25 13:39:56.507 TRACE 14160 --- [nio-8080-exec-5] o.h.type.descriptor.sql.BasicBinder      : binding parameter [1] as [BIGINT] - [2] Hibernate: 
select
    products0_.category_id as categor11_1_0_,
    products0_.id as id1_1_0_,
    products0_.id as id1_1_1_,
    products0_.category_id as categor11_1_1_,
    products0_.created_by as created_2_1_1_,
    products0_.created_dt as created_3_1_1_,
    products0_.description as descript4_1_1_,
    products0_.image as image5_1_1_,
    products0_.is_favorite as is_favor6_1_1_,
    products0_.price as price7_1_1_,
    products0_.title as title8_1_1_,
    products0_.updated_by as updated_9_1_1_,
    products0_.updated_dt as updated10_1_1_ 
from
    product_master products0_ 
where
    products0_.category_id=?

此处要解决的问题陈述是产品数量查询将是类别表中的行数。我们希望这是延迟加载,并且不希望在选择类别时对产品执行多个查询。

tsm1rwdh

tsm1rwdh1#

如果需要单个查询,则应使用左连接提取:

select c from Category c left join fetch c.products

而对于多个类别的问题,请阅读本文https://vladmihalcea.com/jpql-distinct-jpa-hibernate/

gmxoilav

gmxoilav2#

OneToMany关系本质上是惰性的,但设置Fetch(FetchMode.JOIN)将覆盖此惰性行为,因此如果您希望产品的惰性获取,则应将其删除

相关问题