2016-03-04 23 views
1

我有使用UUID作爲PRIMARY KEY一個實體,它產生休眠:是否可以修改生成的值?

@Id 
@Column(name = "uuid") 
@GeneratedValue(generator = "uuid2") 
@GenericGenerator(name = "uuid2", strategy = "uuid2") 
private UUID uuid; 

我怎麼能告訴Hibernate來使用一個明確的值或者我可以修改Hibernate生成的價值?

編輯:我的問題是,在大多數情況下,它的罰款所產生的價值,但在某些情況下,我想有一個明確的UUID創建一個實體。

我的解決方法(ASLO通過以下Dipali Vasani建議)

@Id 
@Column(name = "uuid") 
private UUID uuid; 
/** 
* if defined, this will be used instead of the generated one 
*/ 
private transient UUID preferredUuid; 

@PrePersist 
private void initializeUuid() { 
    if (preferredUuid != null) { 
     uuid = preferredUuid; 
    } 
    else { 
     uuid = UUID.randomUUID(); 
    } 
} 

回答

1

選項1: 是指這樣一個問題:

Does JPA have something like hibernates '@GenericGenerator' for generating custom ids?

和答案:

https://stackoverflow.com/a/7462096/1982680

他們已經使用@PrePersist

你可以使用它像:

@PrePersist 
    public void ensureUuid() { 
    uuid= ... 
    } 

選項2: 創建自定義序列

import java.util.UUID; 
import java.util.Vector; 

import org.eclipse.persistence.config.SessionCustomizer; 
import org.eclipse.persistence.internal.databaseaccess.Accessor; 
import org.eclipse.persistence.internal.sessions.AbstractSession; 
import org.eclipse.persistence.sequencing.Sequence; 
import org.eclipse.persistence.sessions.Session; 

public class UUIDSequence extends Sequence implements SessionCustomizer { 

    public UUIDSequence() { 
     super(); 
    } 

    public UUIDSequence(String name) { 
     super(name); 
    } 

    @Override 
    public Object getGeneratedValue(Accessor accessor, 
      AbstractSession writeSession, String seqName) { 
     return UUID.randomUUID().toString().toUpperCase(); 
    } 

    @Override 
    public Vector getGeneratedVector(Accessor accessor, 
      AbstractSession writeSession, String seqName, int size) { 
     return null; 
    } 

    @Override 
    protected void onConnect() { 
    } 

    @Override 
    protected void onDisconnect() { 
    } 

    @Override 
    public boolean shouldAcquireValueAfterInsert() { 
     return false; 
    } 

    @Override 
    public boolean shouldOverrideExistingValue(String seqName, 
      Object existingValue) { 
     return ((String) existingValue).isEmpty(); 
    } 

    @Override 
    public boolean shouldUseTransaction() { 
     return false; 
    } 

    @Override 
    public boolean shouldUsePreallocation() { 
     return false; 
    } 

    public void customize(Session session) throws Exception { 
     UUIDSequence sequence = new UUIDSequence("system-uuid"); 

     session.getLogin().addSequence(sequence); 
    } 

} 

註冊序列

定製可以被指定爲在API持久性單元屬性:

properties.put(PersistenceUnitProperties.SESSION_CUSTOMIZER, 
       "eclipselink.example.UUIDSequence"); 

或在XML:

<property name="eclipselink.session.customizer" value="eclipselink.example.UUIDSequence"/> 

使用序列

@Id 
@GeneratedValue(generator="system-uuid") 
@Column(name="uuid") 
private UUID uuid; 
+0

感謝。我也在使用選項1。你知道這一代何時發生?看起來它發生在@PrePersist之後,所以要使用選項1,我們不需要用任何生成器來裝飾字段。 –

+0

@PrePersist是在實體管理器持久操作實際執行或級聯之前執行的回調。與持久性操作同步。所以你可以去用它。 –

+0

選項2不適用於我。也許我的問題還不清楚。基本上在大多數情況下,生成值是完全正確的,但在少數情況下,我想使用顯式uuid創建一個實體。所以一旦生成它就無法修改這個值了? –