我是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);
}
不幸的是,这个方法返回集合为集合:(在集合中可以是重复的消息。我需要得到具有重复的集合。你能帮我重写代码并找到解决方案吗?非常感谢。
1条答案
按热度按时间7rtdyuoh1#
如果你很在意重复性,那么你应该通过某种代理键使消息唯一来建模。我猜你有一个
sentMessages
的连接表吧?也许把它建模为一个实体并使用它比使用User
更好。然后你必须创建一个SentMessageRepository
,但它会受到Spring Data的限制。另外,它在语义上更正确IMO。