【问题标题】:Pageable not giving expected results with @ManyToMany relationship可分页未通过 @ManyToMany 关系给出预期结果
【发布时间】:2020-11-13 12:28:25
【问题描述】:

我们正在处理 @ManyToMany 与用户和角色的关系,并希望通过使用 Pageable 接口进行分页以获取具有关联角色的所有用户。它只考虑用户表上的分页记录计数,不考虑角色表记录。但理想情况下,在 RDBMS 中,实际记录数应该是在将用户和角色表之间的连接结果展平之后。

findAll 方法中使用Pageable 并传递如下页面配置时:

pageno: 0 and pageSize:1

    Pageable paging = PageRequest.of(0, 1);
    userRepository.findAll(paging);

它给出的结果如下

技术上,当我们展平结果时有 3 条记录,但 pageable 认为这是 1 条记录,这是不正确的。这是预期的行为吗?

有没有一种方法可以在展平查询结果集后获得分页?

【问题讨论】:

  • 您正在呼叫userRepository。就userRepository 而言,一个userone 计数。可能您想创建一个UserRole 实体和UserRoleRepository,它会为您提供展平记录,并将其计为 3 条记录
  • 感谢@KavithakaranKanapathippillai 的快速响应、建议和编辑。将尝试这种方法

标签: spring jpa pagination pageable


【解决方案1】:

是的。这是有意的。数据作为嵌套对象映射到 Java 对象。因此,5 个用户记录的可分页将返回 5 个用户,而与每个用户拥有的角色数量无关。

要通过用户和角色的组合来限制基于记录计数的分页,您必须将用户和角色之间的联接添加到存储库方法中的查询中,并从用户和角色中获取列(就像我们在 SQL 中所做的那样)。

下面的代码对我有用

用户实体

public class User
{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long userId;
    
    @NonNull
    @Column(unique = true, name= "user_name")
    private String userName;
    
    @NonNull
    private String password;
    
    @NonNull
    private boolean status;
    
    @NonNull
    private boolean passwordExpired;
    
    
    @ManyToMany(fetch=FetchType.EAGER,cascade = CascadeType.ALL)
    @JoinTable(name = "user_role", joinColumns = {
            @JoinColumn(name = "userId", referencedColumnName = "userId") }, inverseJoinColumns = {
                    @JoinColumn(name = "role_name", referencedColumnName = "name") })

    @BatchSize(size = 20)
    private Set<Role> roles = new HashSet<>();
//Get and set
}

角色实体

public class Role  {

    private static final long serialVersionUID = 1L;

    @NotNull
    @Size(max = 50)
    @Id
    @Column(length = 50,unique=true)
    private String name;
//get and set
    
}

存储库

@Repository
public interface UserRepo extends JpaRepository<User, Long>
{   
    @Query(value="SELECT u.userName,r.name FROM User u left join u.roles r")
    public ArrayList<User> findByrole(Pageable paging);
}

服务方式

public ArrayList<User> findByrole() 
    {
        // TODO Auto-generated method stub
        Pageable paging = PageRequest.of(0, 4);
        return uRepo.findByrole(paging);
    }

【讨论】:

  • 感谢@sridhar 的快速响应和示例示例以及解释.. 将尝试这种方法...
  • @ManojKumar 让我知道它是否解决了您的问题。另外,如果这确实解决了您的问题,请将其标记为答案
  • 是的 Sridhar ,它确实帮助我向前思考并实现了解决方案。我有点困惑,决定是使用 join 还是创建一个 UserRole Join Table 存储库,正如上面 Kavithakaran Kanapathippillai 所建议的那样。无论如何它对我帮助很大,我将其标记为答案。感谢您的建议跨度>
猜你喜欢
  • 1970-01-01
  • 2019-12-28
  • 1970-01-01
  • 2021-04-14
  • 2021-09-15
  • 2016-01-30
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多