2016-11-02 76 views
5

我有一個非常簡單的實體,如:如何在持久化實體時實現回調?

@Entity 
public class entityA { 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    private Long id; 

    public entityA(){} 

} 

至於我的理解價值id如果實體被持久化時,才設置。它是否正確?

由於我想將id的值傳播給一些觀察者,這隻有在物品持久後纔有意義。所以我需要一些回調(如void onPersit()entityA。如果實體持續存在,則自動執行方法entityA.onPersit()。如何實現這一點?

(How)一個實體可以確定它自己的狀態。例如。是否有某種this.isPersisted()this.isDetached()

回答

3

如果我在那裏你,我會說是JPA規範中提供的解決方案中,@PostPersist註釋去。你的實體應該是這樣的:

@Entity 
public class entityA { 

    @Id 
    @GeneratedValue(strategy = GenerationType.TABLE) 
    private Long id; 

    public entityA(){} 

    @PostPersist 
    public void onPersit() { 
     // logic to perform after the entity has been persisted 
    } 

} 

Java Persistence 2.1 Specification解釋了這樣的功能:

的PostPersist和刪除後調用回調方法爲一個實體的實體已變得持久或刪除後。這些回調也將在這些操作級聯的所有實體上調用。 PostPersist和PostRemove方法將分別在數據庫插入和刪除操作之後調用。這些數據庫操作可能在 持續,合併或移除操作被調用後直接發生,或者它們可能在發生刷新操作後(可能在事務結束時)直接發生。生成的主鍵值在PostPersist方法中可用。

上面的引用也回答你的問題,如果生成的主鍵只有在插入數據庫之後纔可用。您的假設是正確的,但它將在註釋爲@PostPersist的方法中可用。


關於關於有實體上的方法來檢查其狀態的問題,用簡單的方式是檢查@Id字段是否null與否。如果代碼是由本書編寫的(即不修改該字段本身),這將起作用。

然而,有一個更復雜的實現這一點,在this answer建議:

@Transient 
private boolean persisted; 

@PostLoad 
@PostPersist 
public void setPersisted() { 
    persisted = true; 
} 

通過使用@PostLoad@PostPersist回調,這可以確保persisted場的設置是否正確。同樣,您需要確保您不要修改此方法之外的字段。 @Transient註釋確保該字段不是序列化的候選字段,因此不是持久的。

這些解決方案都可以放置在抽象實體類中,以便跨實體重用。

1

選項(1):擴展org.hibernate.EmptyInterceptor類,如下:

public class MyInterceptor extends EmptyInterceptor { 

    //override postFlush() which eill be called after entity is committed into database 
    public void postFlush(Iterator iterator) { 
     //add your code here 
    } 

    //You can override other required methods like onDelete(), etc.. 

} 

您需要設置interceptor objectHibernate session如下(你需要集中在一個共同的方法,下面的邏輯,否則變像樣板代碼):

MyInterceptor interceptor = new MyInterceptor(); 
session = HibernateUtil.getSessionFactory().openSession(interceptor); 
interceptor.setSession(session); 

你可以看一下API here

選擇(2):實現org.hibernate.event.PostInsertEventListener接口

你可以看一下API here

+0

好的謝謝。我會看看它。 – BerndGit

+0

我無法導入'HibernateUtil'。如何將它包含在項目中(使用'Gradle')? – BerndGit

+0

它應該來自Hibernate JAR https://docs.jboss.org/hibernate/orm/4.0/javadocs/org/hibernate/cache/ehcache/internal/util/HibernateUtil.html – developer