简体   繁体   中英

Spring Data JPA Property Expressions for a many to many query

I'm using Spring boot 2, with Spring data & Spring Data JPA, and I'm looking to replace some existing @Query methods with Spring Data JPA's Property Expressions

However I'm struggling to workout the expression name for a many to many relationship. I'm not too sure if this is possible, as all the example I've seen are based on a one-to-many relationship.

A basic example could be:

Book Entity

@Entity
@Table(name = "book")
public class Book {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

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

    @ManyToMany(mappedBy = "authors", cascade = CascadeType.REFRESH, fetch = FetchType.LAZY)
    private Set<Author> authors = new HashSet<>();

    // Getter and Setters
}

Author Entity

@Entity
@Table(name = "Author")
public class Author {

    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "forename")
    private String firstName;

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

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(
        name = "author_books",
        joinColumns = @JoinColumn(name = "author_id", referencedColumnName = "id"),
        inverseJoinColumns = @JoinColumn(name = "book_id", referencedColumnName = "id"),
        uniqueConstraints = @UniqueConstraint(columnNames = {"author_id", "book_id"})
    )
    private Set<Book> books = new HashSet<>();

    // Getter and Setters
}

The current SQL query looks something like this:

SELECT *
FROM book
LEFT JOIN author_books ON author_books.book_id = book.id
WHERE author_books.author_id = 1;

How would you write the equivalent Spring JPA Property Expressions (if possible) within a Book repository?

I've tried the following (with no luck):

List<Book> findByBooks_AuthorId(Long authorId);
List<Book> findByBooks_Author_Id(Long authorId);
List<Book> findByBooks_AuthorsId(Long authorId);
List<Book> findByBooks_Authors_Id(Long authorId);

One solution would be to obtain the author object by it's id, and then calling author.getBooks() . However, I would like to be able to provide filtering and pagination of results using the spring data PageRequest and Specification classes.

Any help would be really appreciated.

What you need is to find books by author's ID. So you need to write it as the method's name:

List<Book> findByAuthorsId(Long id);

That's it! Also it is unnecessary to use @Column (name=...) annotation if the target column's name is the same as entity field's name. Property expressions

have you tried using Query Annotation.. https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.at-query

@Query("SELECT * FROM book LEFT JOIN author_books ON author_books.book_id = book.id WHERE author_books.author_id = ?1")
List<Book> findByBooks_AuthorId(Long authorId);

您可以尝试以下方法:

List<Book> findAllByAuthorId(Author author);

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