【问题标题】:Spring Data conditionally fetch childrenSpring Data有条件地获取孩子
【发布时间】:2017-07-25 08:17:04
【问题描述】:

我读过Spring Data JPARepository: How to conditionally fetch children entites。 但我想使用方便的 JPA 注释而不是手动加入所有子项。

假设我有以下模型:

@Entity
public class UserModel extends BaseModel<User> {

    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<CredentialModel> credentialList = new ArrayList<>();

    @ManyToMany
    @JoinTable(
            name = "users_actions",
            joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
            inverseJoinColumns = @JoinColumn(name = "action_id", referencedColumnName = "id")
    )
    private List<ActionMode> actionList = new ArrayList<>();
}

获取credentialListactionList 可能是一项耗时的操作(加入获取等)。我不想自动获取 credentialListactionList 。但是当我访问它们时,我希望它们是一个空列表而不是LazyInitializationException

即使我没有在@Query 中特别指定JOIN FETCH 字段,我也可以使用这些字段吗?只需将其保留为空列表即可。

如果没有,有没有办法实现同样的需求?

【问题讨论】:

  • 这有什么意义?如果它们不代表实体关系,为什么还要在实体中定义它们?
  • 正如 galovics 所说,这样做有点麻烦。如果您假设某些内容是空的,那么您不应该处理它,仅此而已。如果您希望它被动态加载,那么延迟加载是要走的路。同样正如 SCI 指出的那样,您可以构建一个跳过集合的实体,我假设 BaseModel 是您代码中的那个实体。这里的问题是,如果你不打算使用它们,你为什么要写它们?

标签: java jpa spring-data


【解决方案1】:

返回空集合会导致一个问题:您无法区分真正空的集合和一个没有延迟加载的集合。 您可以在通过org.hibernate.Hibernate.isInitialized(...) 访问它们之前检查这些集合,或者 PersistenceUnitUtil#isLoaded(...) 在 JPA2 中。

但是,我建议您此时使用 Data-Transfer-Objects。 对于不需要集合的特殊用例,只需构建您的实体的类似副本,而不需要那些不必要的属性。当然,您的 DTO 构建必须在公开会话中完成。

【讨论】:

    【解决方案2】:

    我认为您正在尝试执行 JOIN 而不是 FETCH,可能只是在 where 条件下使用子对象的属性。我想知道这样的事情会在 JPQL 中起作用。

    @Query("Select u from UserModel u INNER JOIN u.credentialList c
     INNER JOIN u.actionList a")
    

    【讨论】:

      猜你喜欢
      • 2016-01-20
      • 2018-01-15
      • 2018-07-02
      • 1970-01-01
      • 2013-07-27
      • 1970-01-01
      • 1970-01-01
      • 2016-12-24
      • 2013-09-27
      相关资源
      最近更新 更多