1

我正在使用 Envers 来审核我的实体的不同字段。该框架通常可以工作,但似乎在某些实体映射方面存在问题。所有以前的问题我都可以自己解决……但这一次我被困住了。

将某些实体插入数据库时​​,出现以下异常:

Caused by: java.lang.NullPointerException
    at org.hibernate.envers.event.AuditEventListener.generateBidirectionalCollectionChangeWorkUnits(AuditEventListener.java:108)

我不能完全确定是哪个实体导致了这种情况,因为它是在 flush() 期间触发的,并且复杂的应用程序在一个更大的事务中插入了许多不同的实体。

我们正在使用一些在该异常之前触发的 HibernateEventListener ......所以我认为该实体是原因。persistence.xml 是这样配置的:

        <property name="hibernate.ejb.event.post-insert" value="com.xyz.hibernate.events.listeners.MyListener,org.hibernate.envers.event.AuditEventListener" />

如果这是真的,那么实体如下(摘录):

@Entity
@Table(name = Property.TABLE_NAME, uniqueConstraints = @UniqueConstraint(columnNames = { "ENTITY_ID", "DESCRIPTOR_ID", "PROMOLEVEL_ID" }))
public class Property extends AbstractEntity {
private static final long serialVersionUID = 1L;

public static final String TABLE_NAME = "E_BUSINESS_PROPERTIES";
public static final String PROPERTY_ENTITY = "entity";
public static final String PROPERTY_DESCRIPTOR = "descriptor";
public static final String PROPERTY_PROMOLEVEL = "promolevel";

@Audited
@ManyToOne(optional = false)
private ProjectPropertyDescriptor descriptor;

@Audited
@ManyToOne
private ExtendedEntity entity;

@Audited
@ManyToOne
private AbstractPromotionLevel promolevel;

@Audited
@OneToMany(cascade = { CascadeType.ALL }, mappedBy = PropertyValue.PROPERTY_PROPERTY)
private List<PropertyValue> propertyValues = new ArrayList<PropertyValue>();

// some accessors stripped!

} 

有谁知道在哪里寻找?一旦我们禁用 Envers,一切正常。但是我们需要envers来生成变化的历史。

4

1 回答 1

9

我找到了我的问题的解决方案。所以我会分享给其他人。

对 ExtendedEntity 的引用导致了问题。ExtendedEntity 是具有不同子类的审计类。但是 Envers 不会自动将子类标记为已审核。子类必须使用 @Audited 注解,以便 Envers 审计该类或任何自己的字段。

因此,对经过审计的 ExtendedEntity 的任何子类的引用都有效。在我的例子中,我引用了另一个未被 Envers 审计的子类——因此抛出了 NullPointerException。通过简单地将 @Audited 注释添加到 ExtendedEntity 类的空扩展(没有自己的属性......只是一个子类来区分另一种类型的实体)并在数据库中创建相关的版本控制表,我可以缩小这个差距并解决我的问题问题。

请记住在任何自己的字段或类本身上用@Audited 标记子类 - 否则它们不会被审计,您可能会遇到完全相同的问题。

于 2009-11-21T21:36:04.453 回答