【问题标题】:Spring JPA fetch subset of OneToMany relationSpring JPA 获取 OneToMany 关系的子集
【发布时间】:2021-04-10 23:57:00
【问题描述】:

我有两张桌子

  • 文章
  • 评论
@Entity(name = "articles")
data class Article(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long,

    @Column(name = "body")
    val body: String,

    @Column(name = "username")
    val username: String,

    @OneToMany
    val comments: List<Comment>,

    )
@Entity(name = "comments")
data class Comment(
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long,

    @Column(name = "username")
    val username: String,

    @Column(name = "text")
    val text: String,

    )

在存储库中:

interface ArticlesRepository : JpaRepository<Article, Long>{
    
    fun findArticlesByUsername(username:String):List<Article>
}

Kotlin 中的代码

我只想获取所有文章和特定用户 cmets 的列表。

用查询用户(不是所有的 cmets)制作的 cmets 集查询文章的最佳方法是什么?

我发现有 Hibernate @Fetch 注释(例如@Fetch(FetchMode.SELECT))但不确定它是否可以使用或如何使用它。

数据示例:

- article_a
  - comment_1 by user_x
  - comment_2 by user_z
- article_b
  - comment_1 by user_x
- article_c

我想查询user_z的文章+cmets 所以结果是:

- article_a
  - comment_2 by user_z
- article_b
- article_c

对不起,我是新手,我正在尝试使用最佳实践来做到这一点。

谢谢

【问题讨论】:

    标签: hibernate spring-data-jpa


    【解决方案1】:

    @Fetch 注释不会帮助您,因为它会影响 fetching behavior 不过滤。

    我猜你可以尝试在这里使用@Filter注解。

    1. 您可以通过以下方式更正映射:
    @Entity(name = "articles")
    data class Article(
    
        // ...
    
        @OneToMany
        @Filter(
           name="commentUser",
           condition="username = :name"
        )
        val comments: List<Comment>,
    
    )
    
    1. 然后您可以启用过滤器:
    entityManager
        .unwrap( Session.class )
        .enableFilter("commentUser")
        .setParameter("name", "user_z");
    
    1. 然后调用您的ArticlesRepository.findArticlesByUsername 方法。

    另请参阅休眠文档的this section

    附:我对 Kotlin 不熟悉,所以语法可能需要更正。

    【讨论】:

    • 是否可以将过滤器与ArticlesRepository.findAll 一起使用?因为ArticlesRepository.findArticlesByUsername 现在将按用户名过滤文章。
    • 实际上我无法让过滤器使用存储库工作,但它确实使用entityManager.createQuery("select a from articles a")
    • 是的,过滤器应该适用于ArticlesRepository.findAllArticlesRepository.findArticlesByUsername,更一般地适用于在from 子句中使用Article 的所有查询。请参阅this 答案作为附加示例。
    • 谢谢,我发现它不见了@Transactional
    猜你喜欢
    • 2013-11-09
    • 2021-02-10
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 2017-01-23
    • 1970-01-01
    • 1970-01-01
    • 2019-10-25
    相关资源
    最近更新 更多