java 获取集合时,JPA延迟获取不工作

h6my8fg2  于 2023-02-20  发布在  Java
关注(0)|答案(1)|浏览(122)

我正在获取一个对象集合,并试图在@ManyToOne关系中使用LAZY加载来获取对象,但是,当我调用服务方法时,集合中的对象得到了NULL值

List<Location> all = locationRepository.getLocations(ids);
Merchant merchant = all.get(0).getMerchant();
// merchant == null
    • 位置存储库. 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);
    }
    • 位置. 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;
    • 商家. 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);
    • 附言**

当我只得到一个对象时,它工作得非常好。例如:

Merchant merchant = locationRepository.findOne("11111").getMerchant();
    • 更新**

原来我对底层问题的理解是不正确的。在获取集合之前,我使用的是www.example.com(location);操作。原来JPA有两个级别的缓存。我的问题是使用EntityMananager解决缓存清理的,例如:locationRepository.save(location); operation. As it turns out JPA has a couple of levels of caching. My problem was solved cache cleaning using EntityMananager, for example:

entityManager.clear();

更多信息:Invalidating JPA EntityManager session
但只要我的问题没有被正确地问到,我建议Maciej Kowalski给出了正确的答案。谢谢

2o7dmzc5

2o7dmzc51#

**1)**您正在使用本地查询:

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

在这种情况下,延迟加载不起作用,结果对象与持久性上下文没有任何关联。

2)FetchType.LAZY只是对持久性提供者的一个提示。它不必使关联变得懒惰,它可以决定急切地获取它。
**3)**在您的情况下,您甚至不需要自定义查询。

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

相关问题