在不检查@Id 的情况下确定实体是否是新的
Determine if entity is new without checking @Id
有没有办法确定给定的实体 class:
@Entity
class A {
String name;
}
boolean method(Object anyEntity) {
// How can I check here, if this entity is completely new
}
new,我的意思是有人调用了 new A() 甚至可能设置了名称,但从未被保存或保留。
通常可以检查 id,但我想要一种不需要 id 或 getId() 方法的解决方案。
基本上,这个实体是否已持久保存到数据库中,即使在分离模式下也是如此。
@Version 或 getVersion 也不是一个令人满意的解决方案。
也许是Detached || isAttached 可能有效,但我不确定如何在 Hibernates 上进行调用 API。
编辑:
另外澄清一下,我不控制实体,所以我不能向它们添加任何字段。解决方案应尝试利用底层机制来确定这一点。
您可以检查实体是否由 PersistenceContext 管理
EntityManager.contains(entity)
如果 API 方法中的任何一个不可用,那么我们可能可以使用 Listeners: 来实现它。这将适用于 JPA/Hibernate.
如下所示:
@Transient
private boolean isNew;
@PostPersist
@PostLoad
public void setWhetherNew() {
isNew = true;
}
您可以使用瞬态字段并使用 Entity-Listeners 来
设置这个字段。
@Transient
private boolean persisted;
@PostLoad
@PostPersist
public void setPersisted() {
persisted=true;
}
然后您可以使用 persisted
判断该实体是否曾经被持久化。
--编辑--
@PostLoad
是必需的,以便从数据库加载的已持久实体也将 persisted
设置为 true。否则它们将显示为 'new',即使它们可以在数据库中找到。
经过一些工作和对 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());
}
有没有办法确定给定的实体 class:
@Entity
class A {
String name;
}
boolean method(Object anyEntity) {
// How can I check here, if this entity is completely new
}
new,我的意思是有人调用了 new A() 甚至可能设置了名称,但从未被保存或保留。
通常可以检查 id,但我想要一种不需要 id 或 getId() 方法的解决方案。
基本上,这个实体是否已持久保存到数据库中,即使在分离模式下也是如此。
@Version 或 getVersion 也不是一个令人满意的解决方案。
也许是Detached || isAttached 可能有效,但我不确定如何在 Hibernates 上进行调用 API。
编辑:
另外澄清一下,我不控制实体,所以我不能向它们添加任何字段。解决方案应尝试利用底层机制来确定这一点。
您可以检查实体是否由 PersistenceContext 管理
EntityManager.contains(entity)
如果 API 方法中的任何一个不可用,那么我们可能可以使用 Listeners: 来实现它。这将适用于 JPA/Hibernate.
如下所示:
@Transient
private boolean isNew;
@PostPersist
@PostLoad
public void setWhetherNew() {
isNew = true;
}
您可以使用瞬态字段并使用 Entity-Listeners 来 设置这个字段。
@Transient
private boolean persisted;
@PostLoad
@PostPersist
public void setPersisted() {
persisted=true;
}
然后您可以使用 persisted
判断该实体是否曾经被持久化。
--编辑--
@PostLoad
是必需的,以便从数据库加载的已持久实体也将 persisted
设置为 true。否则它们将显示为 'new',即使它们可以在数据库中找到。
经过一些工作和对 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());
}