7

项目使用 Hibernate 3.5、Spring Webflow 2 和 Hibernate Envers 进行审计。Envers 在 hibernate.cfg.xml 中配置。我在实体“ArticleGroup”和“Article”之间有一对多的关系映射。表 'articles' 有一个外键 'article_group_id' 引用表 'article_groups' 中的 id。在前端,当我删除一篇文章时,Hibernate Envers 会为 post-delete 事件抛出约束冲突异常。如果我不使用 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 为空,导致违反约束。有人知道如何解决吗?非常感谢。

4

2 回答 2

8

知道了。在配置文件中设置此属性:

<prop key="org.hibernate.envers.store_data_at_delete">true</prop>

参考: http ://docs.jboss.org/hibernate/envers/3.6/reference/en-US/html/configuration.html 表 3.1。Envers 配置属性 org.hibernate.envers.store_data_at_delete

于 2012-08-14T15:20:02.797 回答
7

如果您正在执行后删除,并且在此操作期间对您要删除的任何其他条目articles_AUD有任何限制articles或任何其他条目,那么您将尝试articles_AUD使用不再存在的引用添加条目。

根据经验,我们将引用保留在审计表之外,以便更好地保留修订历史记录。如果审计表包含对非审计表的约束,那么如果从审计表中删除任何条目,修订历史可能会中断。


在设置时参考您的解决方案org.hibernate.envers.store_data_at_delete

删除实体时是否应将实体数据存储在修订版中(而不是仅将 id 和所有其他属性存储为 null)。这通常不需要,因为数据存在于最后一个版本中。然而,有时,在最后一个修订版中访问它更容易、更有效(然后实体在删除之前包含的数据被存储两次)。

这告诉我审计表中有列NOT NULL,因此违反约束,因为 Envers 试图插入null。您可能希望在审计表中允许 null。

于 2012-08-14T14:12:53.850 回答