我正在使用Spring Data
并定义以下查询:
@Query("SELECT u FROM AppUser u LEFT OUTER JOIN fetch u.userRights a LEFT OUTER JOIN fetch u.userGroups g LEFT OUTER JOIN fetch u.userGroups ug LEFT OUTER JOIN FETCH ug.groupRights where u.login = :login")
public Optional<AppUser> findOneWithCompleteRights(@Param("login") String login);
正如您可能看到的,我希望以其所有访问权限取回登录用户。在启动spring应用程序时,它会遇到:
Caused by: javax.persistence.PersistenceException: org.hibernate.loader.MultipleBagFetchException: cannot simultaneously fetch multiple bags
我检查过以下内容: Multiple fetches with EAGER type in Hibernate with JPA
如果我将所有@XXXToMany
类型更改为java.util.Set
,它会有效,但我想自己决定类型...
如果附加到@Query
方法,则链接解决方案的其他注释(请参见下图)似乎会被忽略。无论如何,第二个没有意义。
@Fetch(FetchMode.SELECT)
@IndexColumn(name="LIST_INDEX")
是否有人有其他解决方案,而不是将类型设置为Set
?
答案 0 :(得分:0)
我也有这个问题。 当要加载的类具有多于List映射类型的属性时,就会发生这种情况。
你可以解决这个问题, 通过改变类型 AppUser.userRights和AppUser.userGroups 从java.util.List到java.util.Set。
答案 1 :(得分:0)
Vlad Mihalcea在this post中以及在StackOverflow的一些答案中所描述的完全不是使用Set这里而不是List。他在帖子中说要使用单独的查询。 但是他不是通过Spring-Data Project提供的@ Query-Annotation提供解决方案,而是使用JPQL语句和entityManager。
因此,要实现单独的查询执行,我认为@Fetch(FetchMode.SELECT)(或SUBSELECT,尚不确定差异)将是一个合适的解决方案。但不是@ Query-Annotation而是类中的属性。
所以您的情况也许是:
class AppUser {
....
@OneToMany
@Fetch(FetchMode.SELECT)
List<UserRights> userRights
....
}
但是在我自己的项目中尝试也不起作用。因此,另一种解决方案可能是以某种方式在@ Query-Annotation的语句中创建多个查询,以根据Vlad的建议采取行动。不确定在Annotation-Parameter本身中是否可行,还是必须要有两个带有两个注释的方法。 / p>
@Query(
"SELECT u FROM AppUser u
LEFT OUTER JOIN fetch u.userRights a
LEFT OUTER JOIN fetch u.userGroups g
LEFT OUTER JOIN fetch u.userGroups ug
LEFT OUTER JOIN FETCH ug.groupRights where u.login = :login"
)
public Optional<AppUser> findOneWithCompleteRights(@Param("login") String login);