gpt4 book ai didi

java - JPA ID生成策略

转载 作者:行者123 更新时间:2023-11-30 11:55:16 37 4
gpt4 key购买 nike

我为 JPA 类定义了一个生成器:

<sequence-generator name="MY_SEQ" allocation-size="-1"
sequence-name="MY_SEQ"
initial-value="100000000" />

在某些情况下,我已经有一个实体的 ID,但是当我插入实体时,Id 是使用生成器生成的。

是否可以定义一个生成器,只在不存在的情况下生成一个 Id?

我正在使用 Hibernate 作为 JPA Provider。

谢谢

最佳答案

我找不到在 JPA 中执行此操作的方法,因此我使用了 Hibernate EJB3 事件监听器。我过度使用 saveWithGeneratedId 来使用反射来检查实体是否有 @Id 注释,然后检查该字段的值。如果它有值,那么我会调用 saveWithRequestedId。否则我让它生成 Id。这很有效,因为如果我需要一个 Id,我仍然可以使用为 Hibernate 设置的序列。反射可能会增加开销,所以我可能会稍微改变一下。我正在考虑在所有实体中使用 getId()getPK() 方法,这样我就不必搜索哪个字段是 @Id

在我使用反射之前,我尝试调用 session.getIdentifier(entity) 来检查,但我得到了 TransientObjectException(“实例未与此 session 关联”)。我无法弄清楚如何在不先保存实体的情况下让实体进入 session ,所以我放弃了。下面是我写的监听器代码。

public class MergeListener extends org.hibernate.ejb.event.EJB3MergeEventListener
{



@Override
protected Serializable saveWithGeneratedId(Object entity, String entityName, Object anything, EventSource source, boolean requiresImmediateIdAccess) {


Integer id = null;


Field[] declaredFields = entity.getClass().getDeclaredFields();

for (Field field : declaredFields) {

Id annotation = field.getAnnotation(javax.persistence.Id.class);

if(annotation!=null) {


try {
Method method = entity.getClass().getMethod("get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1));
Object invoke = method.invoke(entity);

id = (Integer)invoke;


} catch (Exception ex) {
//something failed (method not found..etc) , keep going anyway
}

break;

}
}



if(id == null ||
id == 0) {
return super.saveWithGeneratedId(entity, entityName, anything, source, requiresImmediateIdAccess);
} else {

return super.saveWithRequestedId(entity, id, entityName, anything, source);
}
}
}

然后我必须将监听器添加到我的 persistence.xml

 <property name="hibernate.ejb.event.merge" value="my.package.MergeListener"/>

关于java - JPA ID生成策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5081947/

37 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com