提问者:小点点

Hibernate事件,删除后事件引发约束冲突异常


项目使用 Hibernate 3.5、Spring Webflow 2 和 Hibernate Envers 进行审计。Envers 配置为Hibernate.cfg.xml。我在实体“文章组”和“文章”之间有一对多的关系映射。表“文章”具有外键“article_group_id”引用表“article_groups”中的 id。在前端,当我删除文章时,Hibernate 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)

如您所见,当Enver插入表audit.articles_AUD时,article_group_id为空,这导致了约束冲突。有人知道如何修复它吗?非常感谢。


共2个答案

匿名用户

明白了。在配置文件中设置此属性:

<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.环境配置属性org.hhibernate.Envers.store_data_at_delete

匿名用户

如果您正在进行后期删除,并且articles_AUD文章或您在此操作期间删除的任何其他条目有任何约束,那么您将尝试使用不再存在的引用将条目添加到中。

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

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

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

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