延迟加载(使用FK一对一)问题

时间:2015-07-04 19:36:21

标签: hibernate jpa persistence

执行session.createQuery("来自作者")。list(); 即使关系被标记为optional = false,fetch type = lazy from author-> book也会热切地加载相关的书籍实例信息,如下面生成的sql' s。 我将这种关系作为一对一的关系只是为了理解目的,而不是一对一的关系。是否有可能让作者书变得懒惰,如果是这样,不确定我错过了什么?

Hibernate:选择author0_.AUTHOR_ID作为AUTHOR_I1_0_,author0_.email作为email2_0_,author0_.name作为name3_0_来自AUTHOR author0 _

Hibernate:选择book0_.BOOK_ID为BOOK_ID1_1_0_,book0_.AUTHOR_ID为AUTHOR_I5_1_0_,book0_.description为descript2_1_0_,book0_.PUBLISHED为PUBLISHE3_1_0_,book0_.title为title4_1_0_来自BOOK book0_,其中book0_.AUTHOR_ID =?

Hibernate:选择book0_.BOOK_ID为BOOK_ID1_1_0_,book0_.AUTHOR_ID为AUTHOR_I5_1_0_,book0_.description为descript2_1_0_,book0_.PUBLISHED为PUBLISHE3_1_0_,book0_.title为title4_1_0_来自BOOK book0_,其中book0_.AUTHOR_ID =?

Hibernate:选择book0_.BOOK_ID为BOOK_ID1_1_0_,book0_.AUTHOR_ID为AUTHOR_I5_1_0_,book0_.description为descript2_1_0_,book0_.PUBLISHED为PUBLISHE3_1_0_,book0_.title为title4_1_0_来自BOOK book0_,其中book0_.AUTHOR_ID =?

Hibernate:选择book0_.BOOK_ID为BOOK_ID1_1_0_,book0_.AUTHOR_ID为AUTHOR_I5_1_0_,book0_.description为descript2_1_0_,book0_.PUBLISHED为PUBLISHE3_1_0_,book0_.title为title4_1_0_来自BOOK book0_,其中book0_.AUTHOR_ID =?

Hibernate:选择book0_.BOOK_ID为BOOK_ID1_1_0_,book0_.AUTHOR_ID为AUTHOR_I5_1_0_,book0_.description为descript2_1_0_,book0_.PUBLISHED为PUBLISHE3_1_0_,book0_.title为title4_1_0_来自BOOK book0_,其中book0_.AUTHOR_ID =?

Hibernate:选择book0_.BOOK_ID为BOOK_ID1_1_0_,book0_.AUTHOR_ID为AUTHOR_I5_1_0_,book0_.description为descript2_1_0_,book0_.PUBLISHED为PUBLISHE3_1_0_,book0_.title为title4_1_0_来自BOOK book0_,其中book0_.AUTHOR_ID =?

@Entity
@BatchSize(size=3)
@Table(name = "AUTHOR")
public class Author {
    private long id;
    private String name;
    private String email;
    private Book book;


    public Author() {
    }

    public Author(String name, String email) {
        this.name = name;
        this.email = email;
    }

    @Id
    @Column(name = "AUTHOR_ID")
    @GeneratedValue
    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @OneToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY,optional=false,mappedBy="author")
    public Book getBook() {
        return book;
    }

    public void setBook(Book book) {
        this.book = book;
    }


@Entity
@BatchSize(size=3)
@Table(name = "BOOK")
public class Book {

     private long id;
        private String title;
        private String description;
        private Date publishedDate;

        private Author author;

        public Book() {
        }

        @Id
        @Column(name = "BOOK_ID")
        @GeneratedValue
        public long getId() {
            return id;
        }

        public void setId(long id) {
            this.id = id;
        }

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        @Temporal(TemporalType.DATE)
        @Column(name = "PUBLISHED")
        public Date getPublishedDate() {
            return publishedDate;
        }

        public void setPublishedDate(Date publishedDate) {
            this.publishedDate = publishedDate;
        }

        @OneToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY,optional=false)
        @JoinColumn(name ="AUTHOR_ID",unique=true)
        public Author getAuthor() {
            return author;
        }

        public void setAuthor(Author author) {
            this.author = author;
        }
    }

1 个答案:

答案 0 :(得分:1)

您错过了从AuthorBook的链接不是双向关联的定义所有者,我的意思是它被定义为mappedBy而FK位于Book表。 因此,当检索作者时,它需要查询Book表以检查FK并找出是否有书和每个作者关联的书。这就是为什么你在书桌上看到尽可能多的select语句作为你的作者(它被称为 N + 1查询问题)。

避免它的一种方法是切换关联的所有者方(在作者表中定义FK到书)但你会看到类似的行为查询书。

如果您的担忧是附属查询,则一个选项是在查询中应用提取策略,以强制检索与作者关联的图书。查询将是这样的, session.createQuery("from Author a left join fetch a.book").list();

我告诉你原因和基本解决方案/解决方法,但也有更复杂的选项,你可以在stackoverflow中找到它们。