在不检查@Id的情况下确定实体是否是新的

时间:2015-08-04 10:57:33

标签: hibernate jpa entity

有没有办法确定给定的实例类:

@Entity
class A {

    String name;

}

boolean method(Object anyEntity) {
     // How can I check here, if this entity is completely new    
}

新的,我的意思是有人调用了新的A(),甚至可能设置名称,但从未保存或保留。

通常可以检查id,但我想要一个不需要id或getId()方法的解决方案。

基本上,即使在分离模式下,此实体也已持久保存到数据库中。

@Version或getVersion也不是一个令人满意的解决方案。

也许isDetached || isAttached可能有效,但我不知道如何在Hibernates API上进行调用。

编辑:

另外澄清一下,我不控制实体,因此我无法向它们添加任何字段。解决方案应该尝试利用底层机制来确定这一点。

4 个答案:

答案 0 :(得分:3)

如果任何API方法不可用,那么我们可以使用 Listeners:来实现它。这将适用于 JPA / Hibernate。

如下所示:

@Transient 
private boolean isNew;

@PostPersist
@PostLoad
public void setWhetherNew() {
    isNew = true;
}   

答案 1 :(得分:3)

您可以使用瞬态字段并使用实体监听器 设置此字段。

@Transient
private boolean persisted;

@PostLoad
@PostPersist
public void setPersisted() {
   persisted=true;
}
然后,您可以使用persisted来判断该实体是否曾被持久化。

- 编辑 -

@PostLoad是必需的,以便从数据库加载的已保持实体也将persisted设置为true。否则他们会出现在新的'即使它们可以在DB中找到。

答案 2 :(得分:0)

您可以检查实体是否由PersistenceContext管理

EntityManager.contains(entity)

答案 3 :(得分:0)

经过一些工作和分析Hibernate源代码后,我相信这就是答案:

boolean isNew(T entity) {
        return ((SessionImplementor) session()).getPersistenceContext().getEntry(entity) == null;
}

另一方面,在不依赖实现的情况下获取id可以完成:

    boolean hasId(Object entity) {
            return getId(entity) != null;
    }

    Serializable getId(Object entity) {
            ClassMetadata metadata = metadata(entity);
            if ( metadata.hasIdentifierProperty() ) {
                    return metadata.getIdentifier(entity);
            }
            return null;
    }

    ClassMetadata metadata(Object entity) {
            return getRepository().session().getSessionFactory().getClassMetadata(entity.getClass());
    }