以编程方式获取惰性 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())
应该适合你。
我的实体中有一个延迟获取的字段
@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()
andHibernate.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())
应该适合你。