首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >spring-data-jpa多到多个findByID

spring-data-jpa多到多个findByID
EN

Stack Overflow用户
提问于 2021-01-12 22:30:58
回答 1查看 779关注 0票数 0

我在书和作者之间有很多关系,我有三个表:作者,书和author_book。

代码语言:javascript
复制
@Entity()
@Table(name = "author")
public class Author implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String name;

    @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JoinTable(
            name = "author_book",
            joinColumns = @JoinColumn(name = "author_id"),
            inverseJoinColumns = @JoinColumn(name = "book_id")
    )
    private List<Book> authorBooks = new ArrayList<Book>();

    public Author() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Book> getAuthorBooks() {
        return authorBooks;
    }

    public void setAuthorBooks(List<Book> authorBooks) {
        this.authorBooks = authorBooks;
    }

    @Override
    public String toString() {
        return "Author{" + "name=" + name + ", authorBooks=" + authorBooks + '}';
    }

}


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

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @ManyToMany(mappedBy = "authorBooks", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Author> bookAuthors = new ArrayList<Author>();

    public Book() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<Author> getBookAuthors() {
        return bookAuthors;
    }

    public void setBookAuthors(List<Author> bookAuthors) {
        this.bookAuthors = bookAuthors;
    }

    @Override
    public String toString() {
        return "Book{" + "name=" + name + ", bookAuthors=" + bookAuthors + '}';
    }

}

我可以将数据添加到db中,而不存在任何问题,但是当我想通过id获得作者或书籍时,我可以将数据添加到数据库中。

代码语言:javascript
复制
Optional<Author> optionalAuthor = authorReposi.findById(1L);
System.out.println("Author: " + optionalAuthor.get().toString());

我犯了一个错误:LazyInitialization懒惰地失败了.

我想使用FetchType.LAZY并获得作者或书籍的实例。

谢谢您抽时间见我。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-13 02:12:50

因此,请阅读详细的手册:6.3.10。配置Fetch和LoadGraphs

您的问题只是您的toString()方法是递归的。Authors说打印BooksBooks说打印Authors。小贴士:成功在于细节。

对于loadfetch,您需要使用来自JPAEntityGraph来指定连接的属性。所以:

代码语言:javascript
复制
@Entity()
@Table(name = "author")
@NamedEntityGraph(name = "Book.detail", attributeNodes = @NamedAttributeNode("books"))
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Author {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @ManyToMany
    private List<Book> books;
}

代码语言:javascript
复制
@Entity()
@Table(name = "book")
@Getter
@Setter
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Book {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    @ManyToMany(mappedBy = "books")
    private List<Author> authors;

}

拥有存储库:

代码语言:javascript
复制
public interface AuthorRepository extends JpaRepository<Author, Long>{
    @EntityGraph(value = "Book.detail", type = EntityGraphType.LOAD)
    Author getById(Long id);
}

代码语言:javascript
复制
public interface BookRepository extends JpaRepository<Book, Long>{

}

那你必须自己打印出你想要的。基本上,将toStrings放在Entities中通常会导致问题,但您也应该使用RTFM。

代码语言:javascript
复制
private void read(Long id) {
    Author a = authorRepository.getById(id);
    System.out.println("Author: " + a.getName());
    for( Book b: a.getBooks()) {
        System.out.println("\tBook: " + b.getName());
    }
}

最后,我避免使用像瘟疫这样的Cascade注释。它们是复杂的注释。而且,默认情况下,ManyToManyFetchType.LAZY。重要的注释是mappedBy注释。这将告诉您是哪个实体拥有这种关系。拥有的实体是负责维持关系的实体。双向注释的另一面实际上只适用于查询。没有必要在实体中创建新的ArrayList,因为在查询期间它们将被丢弃。当您需要持久化带有关系的新Author实体时,只需创建一个列表,否则使用查询返回的列表。

代码语言:javascript
复制
private Author save() {
    Book b = bookRepository.save(Book.builder().name("b1").build());
    return authorRepository.save(Author.builder().name("a1").books(Collections.singletonList(b)).build());
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65693017

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档