当你创建一个新的域类实例时(例如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,并在需要时重新加载实例.
| 归档时间: |
|
| 查看次数: |
990 次 |
| 最近记录: |