【问题标题】:Programmatically Fetching a Lazy JPA Field以编程方式获取惰性 JPA 字段
【发布时间】:2015-01-28 22:22:38
【问题描述】:

我的实体中有一个延迟获取的字段

@ElementCollection(fetch = LAZY)
private List<String> emails;

而且我的事务边界在服务类停止,我不想在呈现视图时保持打开状态。我希望我的服务类返回分离的实体。

在我的服务类中,我尝试调用 getter,但这似乎被编译器删除了——也许这是对似乎什么都不做的语句的优化

/* User Service class */
@Transactional
public List<User> getAllUsers() {
  List<User> users = new ArrayList();
  for(User u : userRepo.findAll()) {
    u.getEmails(); // <-- this seem to be erased by the compiler optimization.
    users.add(u);
  }
  return users;
}

因此,我不得不将惰性字段打印到 TRACE 日志中,这样它就不会弄乱生产日志。这样做将确保在实体分离之前预先填充惰性字段:

LOG.trace(u.getEmails().toString());

但是,这个解决方案一点也不漂亮。有没有更好的方法来做到这一点?

我不想将该字段标记为 EAGER,因为我有另一种服务方法,为了提高效率而故意跳过关系。

【问题讨论】:

    标签: java spring hibernate jpa


    【解决方案1】:

    由于您使用的是 Hibernate,因此这可能必须是具体的。我不知道有任何 JPA 功能可以做到这一点。 According to the Hibernate Documentation:

    静态方法Hibernate.initialize()Hibernate.isInitialized() 为应用程序提供了一种使用延迟初始化的集合或代理的便捷方式。 Hibernate.initialize(cat) 将强制初始化代理 cat,只要它的 Session 仍然打开。 Hibernate.initialize( cat.getKittens() )对于小猫的收藏也有类似的效果。

    这应该可以防止编译器删除该调用,并且无需您对返回值进行某种工作来欺骗编译器。所以Hibernate.initialize(u.getEmails()) 应该适合你。

    【讨论】:

      【解决方案2】:

      Hibernate.initialize(u.getEmails())

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-07-27
        • 1970-01-01
        • 2014-04-24
        • 1970-01-01
        • 1970-01-01
        • 2019-06-08
        • 1970-01-01
        相关资源
        最近更新 更多