我们在项目中使用spring data jpa和hibernate。
以下是实体的示例表示。
@Entity
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long authorId;
private String firstName;
@OneToOne(mappedBy = "author")
private Book book;
...
}
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
@OneToOne(fetch= FetchType.LAZY)
private Author author;
...
}
请原谅任何语法问题。
我们只有OneToOne
关联字段,这对我们的设计有很多缺点。
1.作者总是懒洋洋地拿来。
1.我们用作者ID唯一标识Book
1.我们在book表中有authorId
作为外键。
1.如果你仔细理解,我们不能使用authorId
来唯一地标识记录,仅仅是因为hibernate懒惰的关联,即使我们想使用它,在equals和hashcode合约中。如果我们在equals和hashcode中使用author关联,它会急切地为我们不想要的每本书调用author实体。
1.在这里,我们之前遇到了一个障碍,因为book.author.authorId
被用在太多的地方,这需要额外的join或查询author表来获取 * only id *。
- 为了解决这个问题,我们在Book实体中创建了另一个字段authorId。**
- 有了这个字段,我们可以在所有查询中执行类似
book.authorId
的操作,而无需获取作者实体。 - 这是我们在许多论坛中提到的将
insertable
和updateable
设置为false的方法,以便将单个列Map到多个字段。
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String title;
@OneToOne
private Author author;
@Column(name = "authorId", insertable = false,updatable = false)
private Long authorId
...
}
- 到目前为止,我已经测试了以下内容:**
1.使用authorId获取工作正常。
1.它与hql jpql一起工作,带有基本测试
1.但不确定限制。
- 问题:**
1.我所理解的是这个字段是只读的,由hibernate为我设置,我不应该明确地在任何地方更新这个字段,我的理解正确吗?
1.在hql/jpql和sql查询中,我们是否可以安全地使用authorId作为新字段
- hibernate会正确管理此字段吗?
1.我们是否需要显式地设置它?当我创建Book时,我可以这样做
Author author = repository.findById();
Book b = new Book();
b.setAuthor(author)
b.setAuthorId(author.getId)
还有任何其他情况下,我显式地需要设置book.authorId?那么它会被Hibernate正确管理吗?
1条答案
按热度按时间w80xi6nr1#
1.我所理解的是这个字段是只读的,由hibernate为我设置,我不应该明确地在任何地方更新这个字段,我的理解正确吗?
是的,一旦相同的字段用于关联,您就不能触摸它。如果你需要更新数据库中的值,你必须通过更新
Book.author
来完成。在您的实体中,只需在Booke
实体中创建一个私有setter,以确保该字段不会被触及。1.在hql/jpql和sql查询中,我们是否可以安全地使用authorId作为新字段
你可以,但你可能不应该。在你上面的问题中,你写道:
在这里,我们之前遇到了一个障碍,因为book.author.authorId在太多的地方被使用,这需要额外的连接或查询author表,只是为了获得id。
如果你查看生成的代码,你会发现没有生成
join
子句,因为Hibernate足够聪明,可以从Books
表的author_id
列中获取值。也就是说,如果你写JPQL查询像结果查询将是
是的,Hibernate主要依赖于反射,所以即使使用私有访问器,代码也是正确的。
1.我们是否需要显式地设置它?
不,你不必这样做.您需要关心
Book.author
,因为它是关联实体。只要Book.authorId
被注解为@Column(name = "authorId", insertable = false,updatable = false)
,Hibernate就不会期望你更新它,就你的代码而言,这就足够了:P.S.在上面的代码片段中,你可以使用
Author author = repository.getById();
而不是Author author = repository.findById();
来保存一个DB调用,因为JpaRepository.getById()
返回一个带有id
的代理,而不是实际获取数据。