我正在获取对象的集合,并尝试通过@ManyToOne关系中的LAZY加载来获取对象。但是,当我调用service方法时,集合中的对象将获得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();
更新
结果证明我对基本问题的理解不正确。在获取集合之前,我正在使用locationRepository.save(location);。操作。事实证明,JPA具有几个缓存级别。我的问题是使用EntityMananager解决的缓存清理问题,例如:
entityManager.clear();
更多信息在这里: Invalidating JPA EntityManager session
但是,只要我的问题没有正确提出,我建议Maciej Kowalski给出正确的答案。谢谢
答案 0 :(得分:3)
1)您在此处使用本机查询:
@Query(value = "SELECT * FROM b_location WHERE id IN :ids", nativeQuery = true)
在这种情况下,不会进行延迟加载。结果对象与持久性上下文无关。
2) FetchType.LAZY
只是对持久性提供程序的提示。它不必使关联变得懒惰,它可以决定急切地获取它。
3)您甚至不需要自定义查询。这应该起作用:
List<Location> findByIdIn(List<String> ids);