0

Enversによって監査され、1つのコレクションを含むエンティティを指定します。そのdocumentation Envers 1としてHibernate Enver:@AuditJoinTable行が見つからない

エンティティA

@Audited 
    public class A{ 
    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    private int id; 
    .... 
    @OneToMany 
    @JoinColumn(name = "a_id") 
    @AuditJoinTable(name = "A_B_AUDIT" 
      ,inverseJoinColumns = @JoinColumn(name = "a")) 
    private List<B> bs; 
    .... 
} 

エンティティB

@Audited 
public class B{ 
@Id 
private int id; 
.... 
@Column(name = "a_id") 
private int aId; 

@ManyToOne 
@JoinColumn(name = "a_id", insertable = false, updatable = false) 
private A a; 
} 

これらAuditJoinTables(A_B_AUDIT)の付加および欠失の監査情報を格納します。しかし残念ながら、これは動作しておらず、テーブル内の行が欠落しています。

私は私のプロジェクト、次の表を実行し作成されます:

A_AUDIT

B_AUDIT

A_B_AUDIT

を私はオブジェクトとBのオブジェクトを永続化する別々のコントローラをしました。 AとAでBを保存しようとすると、audit_table(A_B_AUDIT)は更新されませんが、B_AUDITの更新版が更新されます。

私はここで何が不足しているか教えていただけますか?

ありがとうございました!

休止Enverバージョン:5.1.4.Final

+0

私はmasterと5.1.4の両方でテストしました。問題の再現ができないため、関係の両側の値をどのように設定するかが非常に具体的でなければなりません。エンティティを作成して永続化する前にエンティティを関連付ける場所にコードを含めることができますか? – Naros

+0

こんにちは@Naros、私はそれらの両方のためのコントローラを分離していますし、マッピング(Hibernate)マッピングに基づいて、私は関連付けを選んでいます。 –

+0

別々のトランザクションで 'B'と' A'を永続させているように聞こえます。あなたがそれらの間に構築している唯一の関連は、識別子が 'A'で' B#aId'です。もしそれが真で、明示的に 'B'を' A'のリストに追加していないのであれば、ジョインテーブルに値を置かないでしまいます。これは永続性がどのように働くかではありません。必要な属性をすべて保持していることを確認する必要があります。そうしないと、部分的な状態になり、Enversは監査履歴を正しく入力しません。これがあなたがやっていることでない場合は、再度実際のコードを投稿する必要があります。 – Naros

答えて

1

としてはコメントで言っ は、あなたの問題は、個別の取引におけるこれら2つのエンティティの永続化を実行しているが、あなたは適切に行っていないということですあなたはHibernateの最初のレベルキャッシュの状態を汚しています。不注意に、あなたはEnversにすべての適切な状態を与えていないためエンティティを適切に監査できないようにしています。

Enversで動作するように、このユースケースのためのためには、あなたはそれが実体Aとの関係についてを知っに思える唯一のものであることを考えれば、あなたのエンティティBの永続性を処理する方法を変更する必要があります。エンティティBの持続期間中

、あなたはおそらくこれを行う必要があります。

これは、エンティティBの持続中に意味
if (b.getAId() != null) { 
    A a = entityManager.find(A.class, b.getAId()); 
    a.getBs().add(b); 
    a = entityManager.merge(a); 

    b.setA(a); 
    entityManager.persist(b); 
} 

、あなたが監査に追加監査の行を取得する必要があり、あなたが期待されるように、テーブルを結合し、 Hibernateの第1レベルキャッシュ内の状態には、2つのエンティティ間のすべての適切な参照が含まれます。

我々は、通常のJPAプロバイダの使用上のモーメントとフォーカスのために確保Enversを置く場合、あなたはBを保持した後、これを行うことができる必要があり、それが働くだろう:

final A theA = b.getA(); 
assertNotNull(theA); 
assertTrue(!theA.getBs().isEmpty()); 
assertTrue(theA.getBs().contains(b)); 

を明らかにあなたが設定されていない場合協会、これらの主張(すべてが通るべきである)はそうしないでしょう。彼らが通過する唯一の時間は、あなたがエンティティBを再クエリーするときですが、それは必要ではありません。

うまくいけば分かります。

関連する問題