2017-03-06 131 views
0

我已經在eclipseLink中實現了EntityListener。我的應用程序是使用spring-boot,spring-data和eclipseLink構建的。當插入1表中的數據時,我有要求在2個表(審計表)中插入記錄。我的Listener中有EntityManager,一切似乎正常。當我調試代碼時,我可以看到我將要保存的實體具有從在DB級維護的序列生成的「id」。但是當事務提交時,我只看到主表數據,但審計表數據沒有被提交。下面是示例代碼:eclipseLink事務問題的彈簧啓動

@Entity 
@Table(name="MyTable") 
@EntityListeners(MyTableListener.class) 
public class MyTable implements Serializable{ 

    private static final long serialVersionUID = -5087505622449571373L; 

    private Long id; 
    // Rest of the fields 

    @Id 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="MASTER_SEQ") 
    @SequenceGenerator(name="MASTER_SEQ",sequenceName="MASTER_SEQ",allocationSize=1) 
    public Long getId() { 
     return id; 
    } 

    // Getters/Setters 
} 

監聽器代碼:

public class MyTableListener extends DescriptorEventAdapter { 

     @Override 
     public void postInsert(DescriptorEvent event) { 
      MyTable msg = (MyTable)((InsertObjectQuery) event.getQuery()).getObject(); 
      EntityManager em = BeanUtil.getBean(EntityManager.class); 
      MyAudit statusAudit = new MyAudit(); 
      statusAudit.setNewVal("NEW"); 
      statusAudit.setOldval(null); 
      statusAudit.setTargetColumnName(targetColumn); 
      statusAudit.setTargetRecordId(msg.getId()); 
      em.persist(statusAudit); 
     } 
    } 

似乎沒有什麼是錯的代碼。但是當我在集合中看到sql日誌爲「FINEST」時,我可以看到插入查詢未被審計表觸發。 我一直在處理這個問題超過2天,不明白究竟是什麼錯誤。請幫幫我。

+0

有些代碼會有幫助。根據問題的當前狀態,我們只能告訴您,您的代碼已損壞。當你在它的時候,添加SQL和事務日誌記錄。 –

+0

已添加代碼。 – rishi

回答

1

您從未在EntityManager上致電flush。我懷疑像下面這樣的事情正在發生:

  1. 您可能通過Spring存儲庫將您的域實體添加到EntityManager。

  2. 某些東西會觸發刷新,可能是Spring的事務處理。

  3. 您的域實體被刷新。

  4. 您的事件偵聽器被觸發。

  5. 您將審計實體添加到EntityManager,但這些實體永遠不會被刷新。

  6. 數據庫連接獲取提交。保存所有內容,但不包括審計線索

如果這個理論正確IST,你應該能夠通過日誌和調試器來驗證,你也許可以修復它,在你的聽衆增加flush通話。

正如你在評論中所描述的那樣,這導致了進一步的問題,這是因爲你正在嘗試做一些你不應該做的事情。

根據this article,JPA規範不允許在回調事件中使用entitymanager。

一般而言,可移植應用程序的生命週期方法不應調用EntityManager或Query操作,訪問其他實體實例或修改同一持久性上下文中的關係。生命週期回調方法可能會修改調用它的實體的非關係狀態。

所以看起來,就像我們被卡在這裏一樣,所以你可能應該考慮一個完全不同的方法,如EclipseLink History tables

+0

是的。你的理解是正確的,我的審計實體沒有被刷新,我已經在sql日誌中驗證過它。但我已經嘗試過「沖洗」。如果我使用flush,我會得到「UniqueConstraintsViolation異常」,因爲它會刷新所有內容,並且一旦事務在春天被提交時再次嘗試保存導致相同實體持久化的「MyTable」數據。 – rishi

+0

更新了我的答案。 –