【发布时间】:2014-09-23 12:27:31
【问题描述】:
考虑到用户实例具有名字、姓氏等值,我试图了解如果我们在休眠 session.flush(user) 或 session.evict(user) 中使用没有 id 的实体用户的新用户实例会发生什么
【问题讨论】:
考虑到用户实例具有名字、姓氏等值,我试图了解如果我们在休眠 session.flush(user) 或 session.evict(user) 中使用没有 id 的实体用户的新用户实例会发生什么
【问题讨论】:
如果您创建实体实例并调用 session.flush() 或 session.evict(user),则该实例将不会持久化,即不会写入数据库。
现在的问题是,如果您已将实例设为 Persistent,该怎么办?(通过调用 save()、saveOrUpdate()、persist() 或 merge())。为了持久化一个实例,它是主键,即必须设置 id。如果您在表格中为 id 应用了“auto increment”,则只会保存实例,否则您将收到异常 java.sql.SQLException: Field 'id' doesn't have a default value
我们假设 id 是“自动递增”并且实体是持久的。调用 session.flush() 将显式写入数据库(通常 Hibernate 在会话结束时写入数据库以避免多次 db 命中)。
调用 session.evict(Object) 将使该实例分离。会话关闭或手动刷新会话后,将进入数据库。调用 evict() 后对实例所做的修改不会写入数据库。
Detached - 一个分离的实例是一个持久化的对象,但它的 Session 已经关闭。当然,对对象的引用仍然有效,分离的实例甚至可能在这种状态下被修改。一个分离的实例可以在稍后的时间点重新附加到一个新的 Session 上,使其(以及所有修改)再次持久化。此功能为需要用户思考时间的长时间运行的工作单元启用了编程模型。我们称它们为应用事务,即从用户的角度来看的一个工作单元。
Session#evict(java.lang.Object)
从会话缓存中删除此实例。对实例的更改不会与数据库同步。如果关联映射为 cascade="evict",则此操作级联到关联实例。
session.evict() 只是从 Persistent 更改对象的状态-->Detached 即实体从会话缓存中删除。分离并不意味着实例将从数据库中删除。要删除实例,您必须调用 delete() 或 remove()。
刷新是将底层持久存储与内存中保存的持久状态同步的过程。
【讨论】: