以编程方式获取惰性 JPA 字段

Programmatically Fetching a Lazy JPA Field

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

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

我的事务边界停止在服务 class,我不想在呈现视图时保持它打开。我希望我的服务 classes 到 return 个分离的实体。

在我的服务中 class 我尝试调用 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,因为我有另一种服务方法故意跳过关系以提高效率。

Hibernate.initialize(u.getEmails())

由于您使用的是 Hibernate,这可能必须是特定的。我不知道执行此操作的任何 JPA 功能。 According to the Hibernate Documentation:

The static methods Hibernate.initialize() and Hibernate.isInitialized(), provide the application with a convenient way of working with lazily initialized collections or proxies. Hibernate.initialize(cat) will force the initialization of a proxy, cat, as long as its Session is still open. Hibernate.initialize( cat.getKittens() ) has a similar effect for the collection of kittens.

这应该可以防止编译器删除该调用,并且您无需使用 return 值来欺骗编译器。所以 Hibernate.initialize(u.getEmails()) 应该适合你。