1

什么是 grails 中的分离实例。?

请举例说明。

提前致谢。

4

3 回答 3

9

当您创建一个新的域类实例时(例如def u = new User(username: 'me'),Hibernate 对此一无所知。但是当您持久保存它时,例如当您调用时save(),Hibernate 会将插入推送到数据库并将其与当前的 Hibernate Session 关联(不是与 HTTP 会话混淆 - 它们完全不同)。

此外,当您从数据库中单独或作为多个结果列表的一部分加载实例时,您可以访问该实例,但它也与当前会话相关联。这些对象被“附加”到会话中。

这在几个方面很有用。一个是作为一级缓存。get例如,当您调用时def user = User.get(123),它会被检索并附加。但是,如果您get再次使用相同的 id 调用,它会从缓存中检索,并且不需要额外的数据库调用。另一个是脏检查。Hibernate 还会缓存检索到的原始数据,因此当您修改一个或多个字段时,它可以知道哪些(如果有的话)已更改。

对象断开连接的一个问题是延迟加载。在 HTTP 会话中存储对象是很常见的,但是一旦 Hibernate 会话关闭(例如在请求结束时),所有附加的对象都会被分离。如果你有一个未初始化的惰性加载实例或集合,稍后从 HTTP 会话中检索该实例并尝试访问惰性数据,则会导致异常,因为该实例已断开连接,无法连接到数据库以检索懒惰的数据。解决此问题的一种方法是将实例重新附加到当前会话 - 请参阅http://grails.org/doc/latest/ref/Domain%20Classes/attach.html。更好的解决方法是不在会话中存储这样的对象,而是仅存储 id,并在需要时重新加载实例。

于 2013-09-14T19:11:07.790 回答
1

它只是意味着它不再与 Hibernate 会话相关联。

于 2013-09-14T18:39:10.067 回答
0

与 Session 无关的持久类的新实例,在数据库中没有表示,并且没有标识符值被 Hibernate 视为瞬态:

Person person = new Person();
person.setName("Foobar");

// 人处于瞬态

持久实例在数据库中具有表示形式、标识符值并与 Session 相关联。您可以通过将瞬态实例与 Session 关联来使瞬态实例持久化:

Long id = (Long) session.save(person);
// person is now in a persistent state

现在,如果我们关闭 Hibernate Session,持久化实例将成为一个分离的实例:它不再附加到 Session 上(但以后仍然可以修改并重新附加到新的 Session 上)。

整个第 10 章都清楚地解释了所有这些。 使用我只是在上面解释的 Hibernate 文档的对象。绝对是必读的。

于 2013-09-16T09:42:56.927 回答