簡體   English   中英

JPA ID生成策略

[英]JPA ID Generation Strategy

我為JPA類定義了一個生成器:

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

在某些情況下,我已經有一個實體的ID,但是當我插入該實體時,會使用生成器生成ID。

是否可以定義僅在不存在Id時才生成ID的生成器?

我正在使用Hibernate作為JPA提供程序。

謝謝

我找不到在JPA中執行此操作的方法,因此我使用了Hibernate EJB3事件偵聽器。 我過度使用saveWithGeneratedId來使用反射來檢查實體的@Id批注,然后檢查該字段的值。 如果它有一個值,那么我改為調用saveWithRequestedId 否則,我讓它生成ID。 這很好用,因為如果需要Id,我仍然可以使用為Hibernate設置的序列。 反射可能會增加開銷,因此我可能會對其進行一些更改。 我當時在考慮在所有實體中使用getId()getPK()方法,因此不必搜索@Id是哪個字段。

在我使用反射之前,我嘗試調用session.getIdentifier(entity)進行檢查,但是我遇到了TransientObjectException(“實例未與此會話關聯”)。 我無法弄清楚如何在不先保存實體的情況下將其加入會話,所以我放棄了。 以下是我編寫的偵聽器代碼。

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"/>

這不是一個好主意,序列用於代理鍵,在業務上沒有意義,但向您保證,不會重復,因此在插入時不會出錯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM