以编程方式获取延迟JPA字段

时间:2015-01-28 22:22:39

标签: java spring hibernate jpa

我的实体中有一个懒惰的字段

@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,因为我有另一种服务方法,故意跳过关系以提高效率。

2 个答案:

答案 0 :(得分:3)

Hibernate.initialize(u.getEmails())

答案 1 :(得分:3)

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

  

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

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