1

我的问题比较简单:

我有一个实体,其中包含许多我不需要的懒加载集。现在我不想急切地加载所有内容,也不想拥有几种不同的 getSlimEntity()、getFullEntity()、getEntityForSpecialOccasion() 方法。

我想做的是默认使用“slim”版本,然后按需加载惰性内容。这种需求可能源于更改网页上显示“任务”实体的选项卡。新选项卡应显示任务的历史记录。但是,此选项卡不经常使用,因此我不急切地想要数据。

解决方案应该尽可能少地对数据库进行操作,因为数据库性能对我们来说是个问题。

我想出的一个可能的解决方案是使用 Session.buildLockRequest() 将任务“重新附加”到 EntityManager 并在我需要的 Set 上调用 Hibernate.initialize()。它看起来像这样:

public Set<HistoryEntry> getHistory(Task task) {

    Session session = manager.unwrap(Session.class);
    session.buildLockRequest(LockOptions.NONE).lock(task);

    Hibernate.initialize(task.getHistory());

    return task.getHistory();
}

这是一个苗条且相对易于理解的解决方案,数据库也没有更新或任何东西,只是查询有问题的 HistoryEntries。

现在我的问题是:这个解决方案可以使用吗?它会带来我看不到的任何问题吗?调用 buildLockRequest 实际发生了什么?另外,当多个用户查看同一个任务时会不会有问题?

// 编辑:正如所指出的,此解决方案使用可能与其他持久性提供程序不兼容的 Hibernate 特定调用,例如 EclipseLink 或 OpenJPA。由于这个项目只是内部的,这应该不是问题。

4

1 回答 1

2

我不确定使用LockRequest#lock()将对象重新附加到会话(顺便说一下,它的行为很奇怪,因为它不进行任何版本检查或同步更改)是一个好主意。在您的情况下,这似乎是一个合适的解决方案,但它只是一个副作用,我不会依赖此功能。

另一件事是 -正如 MWiesner 在评论中已经指出的那样,在使用时谈论Hibernate特定的调用是不好的。JPA

你有很多选择:

  1. 如果您知道在从 DB 中检索对象时如何使用对象,请使用实体图
  2. 您可以只进行查询检索所有Histories传递的实体。
  3. 如果您知道传递的对象无法更改,您可以通过EntityManager#merge.

为什么不选择以上之一?

于 2016-02-25T09:08:11.757 回答