我的问题相对简单:
我有一个带有许多延迟加载集的实体,我不需要一直使用它。现在我不想急切地加载所有内容,也不想要有几个不同的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。由于这个项目只是内部的,所以这应该不是问题。
答案 0 :(得分:2)
我不确定是否使用LockRequest#lock()
将对象重新连接到会话(顺便说一下,behaves strangely,因为它没有进行任何版本检查或同步更改)是一个好主意。在你的情况下,它似乎是一个合适的解决方案,但它看起来像一个副作用,我不会依赖这个功能。
另一件事是 - 在使用Hibernate
时谈论JPA
特定电话是不好的,正如MWiesner在评论中已经指出的那样。
你有很多选择:
Histories
传递的实体。EntityManager#merge
将其重新附加到持久性上下文。为什么不选择上述之一?