我拥有以下实体:DocumentType,UserGroup,User
DocumentType.java具有@ManyToMany用户组集:
@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(name = "review_type", joinColumns = @JoinColumn(name="doc_type"),
inverseJoinColumns = @JoinColumn(name="user_group_id") )
private Set<UserGroup> reviewUserGroups;
UserGroup.java具有@ManyToMany用户集:
@ManyToMany
@JoinTable(name = "group_users", joinColumns = @JoinColumn(name = "group_id"),
inverseJoinColumns = @JoinColumn(name = "user_id"))
private Set<User> users;
我想实现以下代码:
@Transactional
private void createDocuments(int avgDocsPerUser) {
List<DocumentType> documentTypes = documentTypeRepository.findAll();
int documentTypesCount = documentTypes.size();
List<User> users = userRepository.findAll().stream().filter(user -> !user.isAdmin()).collect(Collectors.toList());
int usersCount = users.size();
int documentsToCreate = (int) Math.floor(Math.random() * (usersCount * avgDocsPerUser)) + 1;
List<Document> documentList = new ArrayList<>();
while (documentList.size() < documentsToCreate) {
DocumentType documentType = documentTypes.get((int) Math.floor(Math.random() * documentTypesCount));
User user = documentType
.getSubmissionUserGroups()
.stream().findAny()
.get().getUsers()
.stream().findAny().get();
// create new document here and add User info to it
}
documentRepository.saveAll(documentList);
}
我不断收到错误的问题:
原因:org.hibernate.LazyInitializationException:无法延迟初始化角色集合:it.akademija.wizards.entities.DocumentType.submissionUserGroups,无法初始化代理-没有会话
我想避免获取EAGER。如何实现此代码,以便我可以随机获取UserType的一部分,该UserGroup的一部分是DocumentType对象中的SubmissionUserGroups。
答案 0 :(得分:0)
部分问题可能是您在@Transactional
方法上使用了private
注释。根据{{3}},这不起作用:
使用代理时,应仅将@Transactional注释应用于具有公共可见性的方法。如果使用@Transactional注释对受保护的,私有的或程序包可见的方法进行注释,则不会引发任何错误,但是带注释的方法不会显示已配置的事务设置。如果需要注释非公共方法,请考虑使用AspectJ(请参见下文)。
此外,我发现从文档类型中获取User
的方式有些难以理解。问题的一部分是您遍历集合,找到内容然后再遍历另一个集合的时间。
将UserRepository
注入此类并在此处进行单独的查询可能会更容易(并且更符合Spring习惯用法)。如果此方法也是公开的,那么我相信它将被包含在同一事务中,这样您就不必承受不得不打开另一个会话的性能开销。
但是,您应该对此进行更多研究。您可能会发现这对其他帖子有帮助:docs。