簡體   English   中英

獲取集合時,JPA Lazy Fetch無法正常工作

[英]JPA Lazy Fetch is not working when getting collection

我正在獲取一個對象集合,並嘗試使用@ManyToOne關系中的LAZY加載來獲取對象。 但是,當我調用服務方法時,我的集合中的對象獲取NULL值

List<Location> all = locationRepository.getLocations(ids);
Merchant merchant = all.get(0).getMerchant();
// merchant == null

LocationRepository.java

@Repository
public interface LocationRepository extends JpaRepository<Location, String> {

    @Query(value = "SELECT * FROM b_location WHERE id IN :ids", nativeQuery = true)
    List<Location> getLocations(@Param("ids") Set<String> ids);
    }

Location.java

@Entity
@Table(name = "b_location")
public class Location {

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

    @Column(name = "merchant_id", nullable = false)
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private Long merchantId;

    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "merchant_id", referencedColumnName = "id", insertable = false, updatable = false)
    private Merchant merchant;

    @Column(name = "is_active")
    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    private boolean isActive;

Merchant.java

@Entity
@Table(name = "b_merchant")
public class Merchant {

    @Id
    @Column(name = "id")
    private Long id;

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

    @Column(name ="is_premium", columnDefinition = "boolean default false", nullable = false)
    private boolean isPremium;

    @JsonInclude(JsonInclude.Include.NON_EMPTY)
    @OneToMany(mappedBy = "merchant", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Set<Location> shops;

我想做什么:

1)調用另一個查詢,例如:

   @Query("SELECT l, l.merchant FROM Location l LEFT JOIN FETCH l.merchant WHERE l.id IN :ids")
    List<Location> getLocations(@Param("ids") List<String> ids);

@Query("SELECT l FROM Location l LEFT JOIN FETCH l.merchant WHERE l.id IN :ids")
        List<Location> getLocations(@Param("ids") List<String> ids);

@Query("from Location l left join fetch l.merchant where l.id IN (:ids)")
List<Location> getLocations(@Param("ids") List<String> ids);

2)將FetchType更改為所有可能的內容(fetch = FetchType.EAGER)

3)使用

List<T> findAll(Iterable<ID> ids);
// and
List<Location> findByIdIn(List<String> ids);

PS

當我只得到一個物體時,它的效果非常好。 例如:

Merchant merchant = locationRepository.findOne("11111").getMerchant();

UPDATE

結果我對潛在問題的理解不正確。 在獲取集合之前,我使用的是locationRepository.save(location); 操作。 事實證明,JPA有幾個級別的緩存。 我的問題是使用EntityMananager解決了緩存清理問題,例如:

entityManager.clear();

更多信息:使JPA EntityManager會話無效

但只要我的問題沒有被正確詢問,我建議Maciej Kowalski給出了正確的答案。 謝謝

1)您在這里使用本機查詢:

@Query(value = "SELECT * FROM b_location WHERE id IN :ids", nativeQuery = true)

在這種情況下,延遲加載不起作用。 結果對象與持久性上下文無關。

2) FetchType.LAZY只是對持久性提供程序的提示。 它不必使關聯變得懶惰,它可能決定急切地獲取它。

3)在您的情況下,您甚至不需要自定義查詢。 這應該工作:

List<Location> findByIdIn(List<String> ids);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM