我知道有很多关于这个问题的类似问题但对我没什么用。
我在Aim和用户之间有 @ManyToOne 关系。
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "user_id", nullable = false, updatable = false)
private User user;
和
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
private Collection<Aim> userAims;
分别
@Override
@Transactional(propagation = Propagation.REQUIRED)
@PreAuthorize("isAuthenticated() and principal.user.isEnabled() == true")
public Aim findById(String aimId) throws NumberFormatException, EntityNotFoundException {
Aim aim = null;
try {
aim = aimRepository.findOne(Long.parseLong(aimId));
} catch (NumberFormatException e) {
throw new InvalidDataAccessApiUsageException(e.getMessage(), e);
}
if (aim == null) throw new EntityNotFoundException("Aim with id: " + aimId + " not found!");
return aim;
}
@OneToMany 关联适用于延迟抓取。方法不会嵌套到另一个 @Transactional 方法,因此 @Transactional 工作正常。
所以记录存在。
注意我没有 LazyInitException
提前致谢!
答案 0 :(得分:2)
我猜测你的findById
方法中的代码,以及标题中对“懒惰初始化不起作用”的引用,你想通过它的数字找到Aim
对象Id,以及关联的User
对象。
为了使用延迟加载来执行此操作,您需要“获取”关联对象,并且(最重要的是)您需要“获取”关联实体的某个字段。
所以try
块中的代码应该是:
aim = aimRepository.findOne(Long.parseLong(aimId));
if (aim != null && aim.getUser() != null) {
aim.getUser().getUserId(); // doesn't need to be assigned to anything
}
或者,如果您有可用的记录器,则可以在调试或跟踪日志消息中使用userId
:
if (aim != null && aim.getUser() != null) {
logger.debug("Lazy-loaded User " + aim.getUser().getUserId());
}
这有额外的好处,你可以调试延迟加载的方式。
顺便说一句,我们发现了一个很难的方法,即当一个查找例程找不到某个东西时会抛出异常是一个坏主意。这是因为您可能希望使用查找例程来确定实体是否存在 NOT 。如果在事务中发生这种情况,您的异常可能会触发意外的回滚(除非您明确忽略它)。最好返回null
并检查,而不是使用try ... catch
。