2010-05-06 41 views
26

我在我的应用程序的Web UI层中有一个JPA实体实例。我想随时知道这个实体是否已经存在于数据库中,或者只存在于用户会话中。如何知道已分离的JPA实体是否已被保留?

它将在业务层,我会使用entitymanager.contains(实体)方法,但在我的UI层,我想我需要一个额外的属性,指示实体是否已保存或不。如何实现?我正在考虑以下选项:

  • JPA属性的缺省值由数据库设置,但会在每次更新后强制执行新读取?
  • 在我的代码中手动设置了一个非JPA属性还是由JPA自动设置?

任何建议/其他建议?

我使用JPA 1与Hibernate 3.2实现,并希望坚持标准。

回答

44

首先,让我们提醒一个实体的各种状态。从JPA 1.0规范(第3.2节的实体实例的生命周期):

本节介绍管理 实体实例的生命周期中的 EntityManager的操作。实体实例可以被表征为 为新的,管理的,分离的或去除的。

  • 一个实体实例具有没有持久化标识,且尚未与持久化上下文关联 。
  • A managed实体实例是一个实例,持久化标识 当前与持久性上下文相关联。
  • 分离实体实例是一个实例与持久标识 不是(或不再)与一个持久上下文相关联。
  • A 删除实体实例是一个具有持久性标识的实例,与持久性上下文相关联,该实例计划从数据库中删除。

和图形说明:

alt text

所以,顾名思义,分离实体已经坚持了,我其实不认为这是你真正的问题。现在,如果你想知道如果一个实体是(即没有任何持久标识),你看这个:

@Transient 
public boolean isNew() { 
    return (this.id == null); 
} 
+0

当然,我想知道如果我的实体是新的。我宁愿使用数据库中设置了默认值的另一个字段,因为我没有为主键使用JPA GeneratedValue策略(我使用UUID为主键设置了跨数据库供应商/ jpa实现/集群兼容性)。 – snowflake 2010-05-06 09:59:33

+2

@snowflake问题是JPA不支持非pk属性的数据库生成值,因此您必须使用JPA提供程序扩展(如@ @ org.hibernate.annotations.Generated),或者在持久化后刷新实体,这是丑陋的。我想知道是否使用'@ GeneratedValue'不会是更好的选择。 – 2010-05-06 10:06:35

+0

谢谢您的评论。你说得对,这很丑陋,我更喜欢用DAO中的一个字段来替代。 – snowflake 2010-05-06 10:15:43