2012-08-14 84 views
4

項目使用Hibernate 3.5,春天的Webflow 2和Hibernate Envers審計。 Envers在hibernate.cfg.xml中配置。我在實體'ArticleGroup'和'Article'之間建立了一對多的關係映射。表'articles'有一個外鍵'article_group_id'對錶'article_groups'中的id的引用。在前端,當我刪除的文章,休眠Envers會拋出後刪除事件約束違反異常。如果我不使用Envers,刪除操作可以正常工作。這兩個實體的定義如下休眠envers,銷燬後事件引發約束違反異常

@Entity 
    @Table(name="article_groups") 
    @Audited 
    public class ArticleGroup implements Serializable { 

     @OneToMany(mappedBy="articleGroup", fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
     @OrderBy("id") 
     private List<Article> articles; 

     // other fields, getters and setters 
    } 

    @Entity 
    @Table(name="articles") 
    @Audited 
    public class Article implements Serializable { 

     @ManyToOne 
     @JoinColumn(name = "article_group_id") 
     private ArticleGroup articleGroup; 

     // other fields, getters, setters 
    } 

文章刪除編碼如下:

@Service("articleManager") 
    public class ArticleManagerImpl implements ArticleManager { 
      // inject dao 
      @SuppressWarnings("unchecked") 
      @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
      public void deleteArticle(Article article, Object articles) { 
      articleDao.delete(article); 
      ((List<Article>) ((OneSelectionTrackingListDataModel)articles).getWrappedData()).remove(article); 
     } 
    } 

約束違反異常:

Hibernate: delete from live.articles where id=? 
Hibernate: select nextval ('hibernate_sequence') 
Hibernate: insert into audit.REVINFO (REVTSTMP, REV) values (?, ?) 
Hibernate: insert into audit.articles_AUD (REVTYPE, content, language, name, order_number, title, article_group_id, id, REV) values (?, ?, ?, ?, ?, ?, ?, ?, ?) 
82828 [http-bio-8080-exec-2] DEBUG org.springframework.orm.hibernate3.HibernateTransactionManager - Initiating transaction rollback after commit exception 
org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update 
... 
Caused by: java.sql.BatchUpdateException: Batch entry 0 insert into audit.articles_AUD (REVTYPE, content, language, name, order_number, title, article_group_id, id, REV) values ('2', NULL, NULL, NULL, NULL, NULL, NULL, '14', '17') was aborted. Call getNextException to see the cause. 
at org.postgresql.jdbc2.AbstractJdbc2Statement$BatchResultHandler.handleError(AbstractJdbc2Statement.java:2619) 

正如你可以看到,當Envers插入到表'audit.articles_AUD',article_group_id爲null,導致違反約束。任何人都知道如何解決它?非常感謝你。

+0

'live.articles_AUD.article_group_id'對'article_group'有一個約束,我會假設嗎?或者它是否對實際的'articles'表有任何限制?如果你正在做一個後刪除操作,'articles_AUD'對'articles'有任何限制,那麼你就會試圖在'articles_AUD'中添加一個條目,以便不再存在的引用。 – bvulaj 2012-08-14 14:05:32

+0

嗨,對不起,審計表名是'審計。articles_AUD」。它對實際商品表沒有任何限制。它只有一個指向'revinfo'表的外鍵。 – Raistlin 2012-08-14 14:14:39

+0

如果您嘗試調用:insert into audit.articles_AUD(REVTYPE,content,language,name,order_number,title,article_group_id,id,REV)會發生什麼情況值('2',NULL,NULL,NULL,NULL,NULL,NULL ,'14','17')從數據庫控制檯?你會得到什麼錯誤? – adamw 2012-08-15 18:37:23

回答

3

如果你做一個後刪除和articles_AUDarticles,或者你這個操作過程中刪除任何其他條目的任何限制,你則可以嘗試添加一個條目到articles_AUD與引用,不復存在。作爲一個經驗法則,我們保留審計表以外的參考,以便更好地保存修訂歷史記錄。如果審計表中包含非審計表的約束那麼如果從審覈表中的任何條目被刪除修訂歷史記錄可能會破裂。


在設置org.hibernate.envers.store_data_at_delete時參考您的解決方案工作。

如果該實體數據被存儲在修訂當實體是 刪除(而不是僅存儲的ID和所有其他性質 空)。這通常不需要,因爲數據是存在於 最後但-一個版本。但是,有時它是更容易和更高效的 訪問它的最後一次修訂(再之前刪除存儲兩倍 實體所包含的數據)。

這告訴我,有你的審計表是NOT NULL列,因此違反約束,如Envers試圖插入null。您可能希望在審計表中允許爲空。

+0

嗨,謝謝你的回覆。審計表'articles_AUD'對錶'articles'沒有任何限制。唯一的外鍵是指向'revinfo'。另一件事是,爲什麼插入語句中的所有值都是NULL?我想他們應該包含刪除的文章的字段值?任何建議?謝謝 – Raistlin 2012-08-14 14:18:04

+0

答覆已更新。 – bvulaj 2012-08-14 19:43:02

+0

@Raistlin是否解決了您的問題? – bvulaj 2013-03-05 16:00:50