执行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;
}
}
答案 0 :(得分:1)
您错过了从Author
到Book
的链接不是双向关联的定义所有者,我的意思是它被定义为mappedBy而FK位于Book
表。
因此,当检索作者时,它需要查询Book表以检查FK并找出是否有书和每个作者关联的书。这就是为什么你在书桌上看到尽可能多的select语句作为你的作者(它被称为 N + 1查询问题)。
避免它的一种方法是切换关联的所有者方(在作者表中定义FK到书)但你会看到类似的行为查询书。
如果您的担忧是附属查询,则一个选项是在查询中应用提取策略,以强制检索与作者关联的图书。查询将是这样的,
session.createQuery("from Author a left join fetch a.book").list();
我告诉你原因和基本解决方案/解决方法,但也有更复杂的选项,你可以在stackoverflow中找到它们。