-
Postgres:15.3
- table: accounts, reckoner, 无外键,一条 reckoner 一定能对应一条 accounts 记录
- spring boot jpa:3.1.0, hibernate:6.2.2.Final
@Entity
public class ReckonerEntity {
@OneToOne(cascade = CascadeType.MERGE, fetch = FetchType.LAZY)
@JoinColumn(name = "from_acct")
private AccountsEntity fromAcctEntity;
}
@Entity
public class AccountsEntity { }
public interface ReckonerRepository extends JpaRepository<ReckonerEntity, UUID>, JpaSpecificationExecutor<ReckonerEntity> { }
@Bean
@Transactional
public CommandLineRunner runner() {
return args -> {
List<ReckonerEntity> reckoner = reckonerRepository.findAll();
ReckonerEntity reckonerEntity = reckoner.get(0);
AccountsEntity fromAcctEntity = reckonerEntity.getFromAcctEntity();
log.info(fromAcctEntity.getName());
};
}
运行之后出错:org.hibernate.LazyInitializationException: could not initialize proxy [.....] - no Session 我尝试了 transactional 所有的 propagation 都不行,这明显是懒加载的错误
解决方案:
- entityGraph 注解的方式
- @Query(".. join fetch.. ")的方式
- 配置 spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true
- ...
但是这所有的解决方案本质上不都是 eager loading 吗??
-
按照我的理解,上面的代码如果是 lazy loading 应该会 log 两条无 join 的 SQL, 但是我能查到的所有解决方案最终都会导致只生成一条 join 的 SQL
- 也就是这本质上就是 eager loading
-
如果自己实现 dao 层, entity 等所有代码不变, 也就是 @PersistenceContext 注入 entityManager 的方式,可以完美的做到 lazy loading ,log 两条 SQL
-
我就不懂了,所以 spring data jpa 就是不能实现 lazy loading 吗??? 我就想要 lazy loading ,不要 eager loading 有什么办法吗