spring-data-jpa 使用JPA规范返回嵌套集合

4ngedf3f  于 2022-11-10  发布在  Spring
关注(0)|答案(1)|浏览(199)

我是JPA规范的新手,我正在尝试通过用户ID从嵌套集合中获取对象。
有2个实体:

@Entity
@Table(name = "message")
public class Message implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private int id;

    @Column(name = "title")
    private String title;

    @Column(name = "message")
    private String message;

    // getters and setters
}

@Entity
@Table(name = "user")
public class User implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "id")
    private int id;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.MERGE)
    @JoinTable(
            name = "user_message_items",
            joinColumns = { @JoinColumn(name = "user_id") },
            inverseJoinColumns = { @JoinColumn(name = "message_id") }
    )
    private List<Message> sentMessages = new ArrayList<>();

    // getters and setters
}

如果我使用JPQL,它就能正常工作

@Repository
public interface MessageRepository extends JpaRepository<Message, Integer>, JpaSpecificationExecutor<Message>
{

    @Query(value = "select messages from User user inner join user.sentMessages messages where user.id = :userId")
    Page<Message> findSentMessagesByUserId(@Param("userId") int userId, Pageable pageable);
}

但是我希望将来使用Specification来过滤值,所以我做了一个。

public Page<Message> getMessagePageByUserId(int pushUserId)
{
    Pageable paging = new OffsetLimitRequest(0, 10);
    Specification<Message> specification = (root, query, criteriaBuilder) -> {
        Root<Message> messageRoot = root;
        Root<User> userRoot = query.from(User.class);
        Expression<List<Message>> messages = userRoot.get("sentMessages");
        return criteriaBuilder.and(criteriaBuilder.equal(userRoot.get("id"), pushUserId), criteriaBuilder.isMember(messageRoot, messages));
    };
    return messageRepository.findAll(specification, paging);
}

不幸的是,这个方法返回集合为集合:(在集合中可以是重复的消息。我需要得到具有重复的集合。你能帮我重写代码并找到解决方案吗?非常感谢。

7rtdyuoh

7rtdyuoh1#

如果你很在意重复性,那么你应该通过某种代理键使消息唯一来建模。我猜你有一个sentMessages的连接表吧?也许把它建模为一个实体并使用它比使用User更好。然后你必须创建一个SentMessageRepository,但它会受到Spring Data的限制。另外,它在语义上更正确IMO。

相关问题