Mohammad Ersan
Mohammad Ersan

Reputation: 12444

Spring JPA fetch subset of OneToMany relation

I have 2 Tables

@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,

    )

and in the repository:

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

Code in Kotlin

I'd like to get the list all articles and specific user comments only.

What would be the best way to query the articles with the set of the comments made by query user (not all comments)?

I found there is Hibernate @Fetch annotation (ex. @Fetch(FetchMode.SELECT)) but not sure how if it can be used or how to use it.

data example:

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

I'd like to query the articles + comments by user_z so the result would be:

- article_a
  - comment_2 by user_z
- article_b
- article_c

sorry im new to this and im trying to use the best practice to do it.

thanks

Upvotes: 1

Views: 762

Answers (1)

SternK
SternK

Reputation: 13111

The @Fetch annotation will not help you as it's affect fetching behavior not filtering.

I guess you can try to use @Filter annotation here.

  1. You can correct your mapping in the following way:
@Entity(name = "articles")
data class Article(

    // ...

    @OneToMany
    @Filter(
       name="commentUser",
       condition="username = :name"
    )
    val comments: List<Comment>,

)
  1. Then you can enable the filter:
entityManager
    .unwrap( Session.class )
    .enableFilter("commentUser")
    .setParameter("name", "user_z");
  1. And then call your ArticlesRepository.findArticlesByUsername method.

See also this section of the hibernate documentation.

P.S. I am not familiar with Kotlin, so the syntax may require correction.

Upvotes: 2

Related Questions