1

Envers を使用して、エンティティのさまざまなフィールドを監査しています。フレームワークは一般的に機能しますが、ある種のエンティティ マッピングに問題があるようです。以前の問題はすべて自分で解決できましたが、今回は行き詰まりました。

データベースにエンティティを挿入すると、次の例外が発生します。

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

これは、flush() 中に起動され、複雑なアプリケーションが 1 つの大きなトランザクション内にさまざまなエンティティを挿入するためです。

その例外の直前に起動する 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 はサブクラスを監査済みとして自動的にマークしません。サブクラスは、Envers によって監査されるクラスまたは独自のフィールドに @Audited アノテーションを使用する必要があります。

そのため、監査された ExtendedEntity のサブクラスへの参照は機能しました。私の場合、Envers によって監査されなかった別のサブクラスを参照したため、NullPointerException がスローされました。@Audited アノテーションを ExtendedEntity クラスの空の拡張 (独自のプロパティはありません... 別の種類のエンティティを区別するためのサブクラスのみ) に追加し、データベースに関連するバージョン管理テーブルを作成するだけで、そのギャップを埋めて問題を解決できます。問題。

独自のフィールドまたはクラス自体でサブクラスを @Audited でマークすることを忘れないでください。そうしないと、サブクラスは監査されず、まったく同じ問題に遭遇する可能性があります。

于 2009-11-21T21:36:04.453 に答える