Hibernate - @OneToOne 关系
Hibernate - @OneToOne relation
我正在尝试建立一对一的关系。在所有者方面,bookIsn
(非主键)指的是目标实体的主键。
现在的问题是,如果我想阅读所有评论 (reviewRepository.findAll()
),如果给定的 bookIsn
:
没有可用的书,则会抛出以下错误
Unable to find com.repository.model.Book with id 1
但预期的行为是,如果找不到书籍,书籍实体将简单地设置为 null
。就像我使用 reviewId
加入列 @JoinColumn( name = "review_id", ... )
而不是 review_isn
.
一样
有人可以解释为什么它使用主键而不是非主属性吗?需要做什么才能让它也适用于非主要属性?
下面两个类:
Review.java:
@Entity
@Data
@Table(name = "review")
public class Review {
@Id
@Column(name="review_id")
private String reviewId;
@Column(name="book_isn")
private String bookIsn;
@OneToOne
@JoinColumn(
name = "book_isn",
referencedColumn = "book_isn",
insertable = false,
updatable = false)
private Book book;
}
Book.java:
@Entity
@Data
@Table(name = "book")
public class Book {
@Id
@Column(name="book_isn")
private String bookId;
@Column(name="book_name")
private String bookName;
}
首先我要说的是,我不建议您将 @Data
lombok 注释与休眠实体 class 一起使用。例如,参见 this 文章。
那么,我建议您以这种方式更正您的 Review
实体映射:
import javax.persistence.Transient;
@Entity
@Table(name = "review")
public class Review
{
private String reviewId;
private Book book;
@Id
@Column(name = "review_id")
public String getReviewId()
{
return reviewId;
}
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "book_isn")
public Book getBook()
{
return book;
}
// setters omitted for brevity
@Transient
public String getBookId()
{
return book != null ? book.getBookId() : null;
}
}
您可以通过以下方式保留您的 Review
实体:
Book b1 = new Book();
b1.setBookId("BK1");
b1.setBookName("Book 1");
Review r1 = new Review();
r1.setReviewId("R1");
r1.setBook(b1);
session.persist(r1);
Review r2 = new Review();
r2.setReviewId("R2");
session.persist(r2); // book_isn is NULL for the R2 Review
P.S。另请注意,由于潜在的性能问题,it is not recommended 使用字符串作为大表的主键类型。
我正在尝试建立一对一的关系。在所有者方面,bookIsn
(非主键)指的是目标实体的主键。
现在的问题是,如果我想阅读所有评论 (reviewRepository.findAll()
),如果给定的 bookIsn
:
Unable to find com.repository.model.Book with id 1
但预期的行为是,如果找不到书籍,书籍实体将简单地设置为 null
。就像我使用 reviewId
加入列 @JoinColumn( name = "review_id", ... )
而不是 review_isn
.
有人可以解释为什么它使用主键而不是非主属性吗?需要做什么才能让它也适用于非主要属性?
下面两个类:
Review.java:
@Entity
@Data
@Table(name = "review")
public class Review {
@Id
@Column(name="review_id")
private String reviewId;
@Column(name="book_isn")
private String bookIsn;
@OneToOne
@JoinColumn(
name = "book_isn",
referencedColumn = "book_isn",
insertable = false,
updatable = false)
private Book book;
}
Book.java:
@Entity
@Data
@Table(name = "book")
public class Book {
@Id
@Column(name="book_isn")
private String bookId;
@Column(name="book_name")
private String bookName;
}
首先我要说的是,我不建议您将 @Data
lombok 注释与休眠实体 class 一起使用。例如,参见 this 文章。
那么,我建议您以这种方式更正您的 Review
实体映射:
import javax.persistence.Transient;
@Entity
@Table(name = "review")
public class Review
{
private String reviewId;
private Book book;
@Id
@Column(name = "review_id")
public String getReviewId()
{
return reviewId;
}
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "book_isn")
public Book getBook()
{
return book;
}
// setters omitted for brevity
@Transient
public String getBookId()
{
return book != null ? book.getBookId() : null;
}
}
您可以通过以下方式保留您的 Review
实体:
Book b1 = new Book();
b1.setBookId("BK1");
b1.setBookName("Book 1");
Review r1 = new Review();
r1.setReviewId("R1");
r1.setBook(b1);
session.persist(r1);
Review r2 = new Review();
r2.setReviewId("R2");
session.persist(r2); // book_isn is NULL for the R2 Review
P.S。另请注意,由于潜在的性能问题,it is not recommended 使用字符串作为大表的主键类型。