Q1.我不确定什么时候应该关联实体,什么时候不应该。
例如:按集合休眠关联
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
@OneToMany(mappedBy = "author")
private Set<Book> books = new HashSet<Book>();
...
}
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
@ManyToOne
private Author author;
...
}
或仅通过id
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String firstName;
...
}
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
private Long authorId;
...
}
Q2.双向关联时,
例如:图书类
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "authorId", unique=true)
private Author author;
...
}
书籍总是具有作者,该作者在书籍实体中是唯一的,
但是由于我们是懒惰地获取,我不能在hashcode中使用它。我只有authorId
作为唯一的方式来识别记录,唯一的等于和哈希码。这种情况下我该怎么办。
1条答案
按热度按时间6l7fqoea1#
回答您的第一个问题:
Q1.我不确定什么时候应该关联实体,什么时候不应该。
参数
简单的回答是总是使用关联。在您提供的示例中,两个实体似乎都与同一个域相关。
1.如果在这种情况下使用id,您将失去持久性提供程序(Hibernate)应用于这些关系的约束- i。例如,提供者不知道所使用的值
Book.authorId
是否对应于Author.id
。当然,您可以在数据库级别强制执行这个约束,但是,这样的话,持久性Map就不能代表您的数据库约束。1.如果您认为关联的另一端的实体太复杂而不能立即检索,则可以使用
@ManyToOne(fetch = FetchType.LAZY)
提示。1.无论好坏,它强制--或者至少应该强制--一个人仔细思考他的模式。所有的关系都是双向的吗?如果没有,则不应在该实体中使用关联。
反对参数
1.这些实体是不同域的一部分。这取决于您的模型,但有时候,持久化上下文保存来自不同域的实体是没有意义的。在这种情况下,最好创建一个值对象来表示另一个域实体的id i即
AuthorId
,并将其Map为@Embedded
。回答你的第二个问题
Q2.使用双向关联时
如果你考虑一个实体类的
Object#equals
和Object#hashCode
契约,那么在这些方法中起作用的唯一属性应该是它的id定义的一部分。具有相同
Book.id
(相同实体)的两个books示例应该总是返回相同的散列。如果你使用Book.author
或Book.authorId
来生成哈希值,情况就不是这样了。然而,即使在
Book#hashCode
方法中使用Book.author
属性,如果Author
实体被延迟检索,也不会有问题。一旦调用了Book#hashCode
方法,Author
实体将首先被检索(并且,按顺序,它的Author#hashCode
方法将被调用)。