简体   繁体   中英

Spring Data JPA conditional entity join

I have unusual table setup that I want mapped in JPA. Here's a simplified example:

book
  company_id int
  book_id    int
  series_id  int

borrow
  company_id int
  book_id    int
  type       char

The problem is borrow.book_id is overloaded:

  • If borrow.type is 'B', then borrow.book_id == book.book_id
  • If borrow.type is 'S', then borrow.book_id == book.series_id

The relation is logically many borrow to one book . The immediate use case is: get all borrow rows given a list of book s. How should this be mapped in Spring Data JPA?

You can try something like below in your Borrow entity mapping for Book -

@ManyToOne
@JoinColumnsOrFormulas(
    { @JoinColumnOrFormula(
        formula = @JoinFormula(
         value = "case " +
                 "when type == 'B' then book_id" +
                 "when type == 'S' then series_id " +
                 "else 1" +
                 "end", 
         referencedColumnName="book_id")) }
)

But you need to use the @ManyToOne annotation, even though this seems to be a @OneToOne association. The join formula won't work on OneToOne. The downside with this approach would be, hibernate will unnecessarily create 2 joins which could be done using only 1 using a native query

If you are using spring data JPA then in your repository you could use method like -

@Query(value="sql stmt with conditional join and IN clause", nativeQuery = true)
List<Idto> findAllBorrowByBook(List<int> bookIds);

where "Idto" is an interface to map your resultset.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM