带有多个集合的JPA分页查询返回错误的实体数
我有这两个实体(这里是简化版本): 主题:带有多个集合的JPA分页查询返回错误的实体数,jpa,pagination,many-to-many,eclipselink,jpql,Jpa,Pagination,Many To Many,Eclipselink,Jpql,我有这两个实体(这里是简化版本): 主题: @Entity public class Topic implements Serializable { @Id @GeneratedValue( strategy = GenerationType.IDENTITY ) private Long id; @ManyToMany @JoinTable( name = "topic_member",
@Entity
public class Topic implements Serializable {
@Id
@GeneratedValue( strategy = GenerationType.IDENTITY )
private Long id;
@ManyToMany
@JoinTable(
name = "topic_member",
joinColumns = @JoinColumn( name = "topic" ),
inverseJoinColumns = @JoinColumn( name = "member" ) )
@JoinFetch
private List<Member> participants = new ArrayList<Member>();
...
它们通过连接表topic\u成员(成员,主题)
通过单向@manytomy关系进行关联
当我插入东西时,一切正常,这里没有问题
但是当我想要选择东西时,它变得更加棘手。假设我要选择与特定成员相关的所有主题。我编写了以下JPQL查询:
SELECT t FROM Topic t WHERE :member MEMBER OF t.participants ORDER BY t.id DESC
然后我写道:
TypedQuery<Topic> query = em.createQuery( MY_JPQL_REQUEST, Topic.class );
query.setParameter( PARAM_MEMBER, member );
return query.getResultList();
TypedQuery query=em.createQuery(MY_JPQL_请求,Topic.class);
query.setParameter(PARAM_成员,MEMBER);
返回query.getResultList();
而且效果很好
但有一个非常奇怪的错误:似乎我不能在这个查询上使用分页!
例如,当我尝试以下方法时:
TypedQuery<Topic> query = em.createQuery( MY_JPQL_REQUEST, Topic.class );
query.setParameter( PARAM_MEMBER, member );
query.setFirstResult( 0 );
query.setMaxResults( 5 );
return query.getResultList();
TypedQuery query=em.createQuery(MY_JPQL_请求,Topic.class);
query.setParameter(PARAM_成员,MEMBER);
query.setFirstResult(0);
query.setMaxResults(5);
返回query.getResultList();
它返回了错误的实体数。例如,当前一个返回5时,它只返回3
我错过了什么?我不明白会出什么问题
我读过,我想这里可能有些东西,但我不知道是什么
[Edit]以下是我在DB的join表中的内容,如果有帮助的话:
+-------------+--------------+
| member | topic |
+-------------+--------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 2 | 5 |
+-------------+--------------+
+-------------+--------------+
|成员|主题|
+-------------+--------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 2 | 5 |
+-------------+--------------+
[Solution]多亏了Chris,我才让它工作起来。我不得不在
@manytomy
字段中将@JoinFetch
替换为@BatchFetch(BatchFetchType.JOIN)
,并查询从…
中选择不同的(t)而不是从…
中选择t这是出于设计。分页在数据库级别工作,以过滤返回的行数。在集合上使用fetch联接时,需要多行来构建单个实体,因此返回的实体数与max结果不匹配。除此之外,为了确保返回完整的实体,可能会丢弃第一个和最后一个实体,因为无法验证它们是否完整
尝试使用批量抓取代替IN策略。谢谢您提供的信息。在我的情况下,我应该如何在策略中选择与特定成员相关的所有主题?我试过了,但一直没能正常工作。是我所指的,而不是join-fetch注释。您所展示的映射是从一个主题到另一个成员的,因此类似于“selectm fromtopict join t.m where t=:t”的内容很不幸,这个请求似乎是错误的。在我的简单设计中,每个主题都有一个成员列表,我想要给定成员的所有主题(=给定成员在其参与者列表中的每个主题)。我肯定错过了一些明显的东西,但如果没有…的成员,我看不出如何做到这一点。批处理获取可以很好地处理原始查询。使用联接获取会导致分页问题。如果仍然存在问题,请尝试使用DISTINCT。好的,非常感谢!最后,JPQL查询中
@ManyToMany
字段+DISTINCT
上的@BatchFetch
(In或JOIN类型,两者都可以正常工作)起到了作用。
+-------------+--------------+
| member | topic |
+-------------+--------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 1 | 5 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 2 | 5 |
+-------------+--------------+