如何在hibernate中识别暂时或分离的对象?

如何在hibernate中识别暂时或分离的对象?,hibernate,Hibernate,我知道transient instance意味着该实例是新创建的,其对应的行在数据库中不存在,其中as detached instance在数据库中有相应的条目,但目前没有与任何会话关联 在hibernate中,是否有任何方法可以通过编程方式使用会话上的任何方法或其他方法来识别暂时或分离的对象?听起来像是在寻找 检查实例是否是属于当前持久性上下文的托管实体实例 Matt建议只检查给定对象是否是瞬态的或与某个实体管理器关联 如果你想检查它是分离的还是暂时的,你不应该真正关心它!它应该是透明的,您需

我知道transient instance意味着该实例是新创建的,其对应的行在数据库中不存在,其中as detached instance在数据库中有相应的条目,但目前没有与任何会话关联


在hibernate中,是否有任何方法可以通过编程方式使用会话上的任何方法或其他方法来识别暂时或分离的对象?

听起来像是在寻找

检查实例是否是属于当前持久性上下文的托管实体实例


Matt建议只检查给定对象是否是瞬态的或与某个实体管理器关联

如果你想检查它是分离的还是暂时的,你不应该真正关心它!它应该是透明的,您需要检查给定对象是否具有ID

if(data.getID() == null) return TRANSIENT;
应仅为持久/分离对象设置ID。如果出于某种原因,您自己在瞬态对象上设置ID,那么我认为您想做的是不可能的

如果出于某种原因,您不知道ID是哪个字段,或者希望使其成为通用字段,您可以尝试:

ClassMetadata metadata = HibernateUtil.getSessionFactory().getClassMetadata(data.getClass());
if(metadata.getIdentifier(data) == null) return TRANSIENT;

为了检查对象e是否在:-

持久性上下文:-EntityManager.containse应返回true

分离状态:PersistenceUnitUtil.getIdentifier返回实体标识符属性的值

瞬态:-PersistenceUnitUtil.getIdentifiere返回null

您可以从EntityManagerFactory访问PersistenceUnitUtil

有两个问题需要注意。首先,请注意标识符值可能不正确 在刷新持久性上下文之前,将一直分配并可用。第二,冬眠 与其他一些JPA提供程序不同,它从不从持久性返回null- UnitUtilgetIdentifier如果标识符属性是一个长而非长的基元
长。

您可以尝试将临时对象和分离对象传递给hibernate会话更新方法,并观察差异。对于临时对象,hibernate将报告错误

所以hibernate知道对象是暂时的或分离的。但是怎么做呢?答案很简单:hibernate将在更新之前进行选择,以获取哪些字段不干净的信息。如果对象是瞬态的,则选择操作将不会产生任何结果,然后hibernate知道这是瞬态对象并报告错误

或者,如果您使用@SelectBeforeUpdateValse,hibernate将不执行选择,而是直接使用更新,在这种情况下,jdbc将报告错误,因为需要更新的行不存在

当然,如果id字段是由数据库生成的,您可以检查它,否则了解其状态的唯一方法是执行查询:未找到表示暂时。

正如其他人所说,org.hibernate.Session.containsObject可以在hibernate中使用,以了解实体实例是否已附加或分离。关于瞬态,我认为最好的方法是org.hibernate.Session.saveOrUpdateObject凭借org.hibernate.persister.entity.AbstractEntityPersister.isTransientObject,SessionImplementor所做的,即:

如果实体没有@Id属性,它总是被认为是暂时的 如果实体的@Id属性值为null,那么它总是被认为是暂时的 如果实体的@Id属性值等于配置的未保存值,那么它被认为是暂时的,只适用于XML映射,我认为这有点不推荐,请参阅 如果它有一个@Version属性,其值是一个新创建的实例的值,也就是说,它是一个空的Long或Date,等等,那么它被认为是暂时的 因此,我认为,对于没有生成id的实体来说,查看@Version属性是一个不错的选择。如果没有这样的属性,则saveOrUpdate中的Hibernate本身会对数据库进行SELECT查询,以确定实体实例是否是暂时的,以确定它是否应该分别执行插入或更新


请参阅Hibernate手册作为示例。

感谢您的回复。但我认为它会检查这个实例是否与持久性上下文关联,对吗?我想这与hibernate中的session.containsobject类似。@MateuszDymczyk我没有否决,但如果你创建一个对象并手动设置它的ID,它仍然是暂时的,我想这是大多数人和我一样来到这里的情况,我是从JSON获得我的对象的decode@MateuszDymczyk另外,getClassMetadata是反射,它有它自己的性能惩罚,我想你应该在你的答案中明确它。