java - JPA Lazy Fetch 在获取集合时不起作用

标签 java spring-boot hibernate jpa spring-data-jpa

我正在获取对象的集合,并试图通过@ManyToOne 关系中的延迟加载来获取对象。但是,当我调用服务方法时,我的集合中的对象获得了 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);
    }

位置.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);

附言

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

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

更新

事实证明我对潜在问题的理解不正确。在获取集合之前,我正在使用 locationRepository.save(location);手术。事实证明 JPA 有几个级别的缓存。我的问题已使用 EntityMananager 解决缓存清理,例如:

entityManager.clear();

更多信息在这里: Invalidating JPA EntityManager session

但只要我的问题没有被正确提出,我建议 Maciej Kowalski 给出了正确的答案。谢谢

最佳答案

1)您在此处使用 native 查询:

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

在这种情况下,延迟加载将不起作用。结果对象与 Persistence Context 没有任何关联。

2) FetchType.LAZY 只是对持久性提供程序的提示。它不必使关联变得惰性,它可能决定急切地获取它。

3) 在您的情况下,您甚至不需要自定义查询。这应该有效:

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

关于java - JPA Lazy Fetch 在获取集合时不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57124111/

相关文章:

java - 无法实例化 @InjectMocks 字段

Hibernate @OnDelete 级联同表

java - 如何从 Facebook 获取 Android Studio 用户名

Azure Web 部署失败 - 给定名称的网站已存在

java - 自执行命令

eclipse - 防止下载Gradle和Maven依赖项

java - 使用jsp从数据库检索数据(Hibernate + Spring + Maven)

java - Hibernate 在 @JoinTable 上创建关系

java - Emacs 枚举缩进

java - 我该如何解决这个问题?