我有以下实体:
@Entity
public class ProjectEntity implements Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(targetEntity = FlowEntity.class)
private Flow flow;
}
@Entity
public class FlowEntity implements Flow {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@OneToMany(targetEntity = StepEntity.class, fetch = FetchType.EAGER)
private List<Step> steps;
}
@Entity
public class StepEntity implements Step {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToMany(targetEntity = ResourceEntity.class, fetch = FetchType.LAZY)
private List<Resource> resources;
@OneToMany(targetEntity = StepRuleEntity.class, fetch = FetchType.LAZY)
private List<StepRule> rules;
@ManyToMany(targetEntity = ResourceTypeDataEntity.class, fetch = FetchType.LAZY)
private List<ResourceTypeData> resourceTypeData;
}
现在当我检索我的项目时,我希望所有内容都已加载。我不能让所有东西都渴望加载,因为它会让一切都变慢。但是对于这个功能,我现在真的需要项目中的所有东西。
我在网上看到你需要在每个集合上调用.size()
方法,然后jpa将加载集合但它不起作用。另外我觉得很奇怪我需要在流程的每一步中在我的dao中执行for
循环来加载下一个延迟加载的集合。
我的方法使用@Transactional
进行注释以获取项目,它是默认的JpaRepostitory
。
你是如何正确地做到这一点的?
答案 0 :(得分:0)
正如评论中所述,您可以在查询中使用fetch
关键字来执行此操作:
@Query("select p from Project p " +
"left join fetch p.flow f " +
"left join fetch f.steps s " +
"left join fetch s.resources " +
"left join fetch s.rules " +
"left join fetch s.resourceTypeData " +
"where p.id = ?1")
Project findByIdEager(Long id);
如果您希望立即获取所有集合,或者您希望保持集合延迟加载,则允许您使用findByIdEager(..)
或者任何默认方法(例如findById(..)
)。
答案 1 :(得分:0)
理想情况下,@ OneToMany默认情况下必须具有延迟加载的关联。因此,在类 FlowEntity 中,必须懒惰地获取步骤。此外,如答案所示,您可以使用JPQL Join FETCH来急切加载所需的关联。