2016-10-03 9 views
0

最近エンベロープに関するエンバブを見つけて、@AuditedアノテーションとAuditReaderを使用してリビジョンを追跡し、フェッチすることができました。さて、私が達成しようとしているのは、最新のリビジョンの代わりに行われたリビジョンで監査されたエンティティへのマッピングを保持することです。JPAアノテーションを使用してエンティティの古いリビジョンにマッピングする

クイック例:

のは、私は(下記のクラスの疑似クラス)クッキーのバッチを作るために使用するクッキーのレシピを持っているとしましょう。各レシピには従うべき命令のリストを持っているし、そうすることはバッチを作成します。

@Audited 
@Table(name="recipes") 
class CookieRecipe { 
    @OneToMany(mappedBy="recipe") 
    private List<RecipeStep> steps; 

    private void addStep(String instruction) { 
     steps.add(new RecipeStep(instruction)); 
    } 
} 

@Table(name="batches") 
class CookieBatch { 
    @ManyToOne 
    @JoinColumn(...) 
    private CookieRecipe recipe; 
} 

@Audited 
@Table(name="recipe_step") 
class RecipeStep { 

    @Column 
    private String instruction; 

    @ManyToOne 
    @JoinColumn(...) 
    private CookieRecipe recipe; 

    private RecipeStep(String instruction) { 
     this.instruction = instruction; 
    } 
} 

さて、私はこのクッキーのレシピ持っているとしましょう:

CookieRecipe recipe = new CookieRecipe(); 
recipe.addStep("Make the dough"); 
recipe.addStep("Place on pan"); 
recipe.addStep("Bake at 400F for 20 minutes"); 
entityManager.persist(recipe); 

を私は作成するためにこのレシピを使用することがありますクッキーの私の最初のバッチ:

CookieBatch batch = new CookieBatch(recipe); 
entityManager.persist(batch); 

私は例えば、言うためにレシピを変更したい場合は、代わりに400Fの375°Fが、これは私が期待して欲しいものである、CookieRecipeのリビジョン2を作成します。しかし、すでに作成したバッチがCookieRecipeのリビジョン1を指すようにしたいと思います。現在、IDを使用してすでに作成したCookieBatchを取得した場合、CookieRecipeへの参照は最新のリビジョン(375Fのもの)になります。

これは私がenversを使用して達成できるものですか?

+0

'CookieBatch'はされていません' @監査された 'は意図的ですか?もしそうなら、私はあなたがやろうとしていることをやり遂げる優雅な方法があるとは思わない。 – SergeiBednar

+0

@SergeiBednarはい、「CookieBatch」が完了しても変更されないという理由だけです。だから私はそれが本当に使用されることはない監査テーブルを作成するので不必要だと思った...私はこの動作を誤解しない限り。私はそれが解決策につながるなら、それに '@ Audited'を追加することに反対していません。 – cklab

+0

あなたの唯一の解決策は、 'recipeId'と' recipeRevisionNumber'の値を保持し、 'CookieBatch'の' recipe'エンティティを '@ Transient'に変更し、あなた自身がレシピのクエリを処理することです'AuditCriteria'、あなたが' CookieBatch'エンティティをロードした後。 – SergeiBednar

答えて

2

これを行う唯一の方法は、CookieBatchrecipeId,フィールドを保存し、CookieRecipeオブジェクトを自分でロードすることです。すべてのもののenversため

Hibernate Envers get revisions for criteria

とドキュメント:

@Table(name="batches") 
class CookieBatch { 

    @Column(...) 
    Long recipeId; 

    @Column(...) 
    Long recipeRevisionNumber; 

    @Transient 
    private CookieRecipe recipe; 

    @PostLoad 
    public void loadRecipe() 
    { 
     // Load a cookie recipe via audit criteria 
    } 
} 

監査基準は、この例をチェックアウトし、かなり自明です

http://docs.jboss.org/envers/docs/

1

CookieBatchCookieRecipeの間の双方向関係を維持するだけでなく、CookieBatchも監査することをお勧めします。このようにして、Enversはどちらかの側から適切なバージョンを正しく照会できます。言い換えれば

は、その後、次のループを使用して適切なバージョン管理データをフェッチすることができますCookieRecipe

@OneToMany(mappedBy = "recipe", cascade = CascadeType.ALL) 
private List<CookieRecipeBatch> batches = new ArrayList<>(); 

に以下を追加します。

AuditReader reader = AuditReaderFactory.get(session); 
for (Number revision : reader.getRevisions(CookieRecipe.class, recipeId)) { 
    CookieRecipe recipe = reader.find(CookieRecipe.class, recipeId, revision); 
    // recipe.getSteps() - contains all steps with revision number <= revision 
    // recipe.getBatches() - contains all batches with revision number <= revision 
} 

上記のあなたの特定のCookieRecipeを与える必要があります適切なバッチおよびステップのスナップショットを使用して修正します。

+0

私の目標は、バッチIDを使用して 'CookieBatch'を取得し、' CookieRecipe'のリビジョンを参照することです。作成時に使用されます。残念ながら、「適切なリビジョン」が何であるかを知っていない、それは欠けているデータです。 @SergeiBednarが推薦しているもののように、特に「CookieBatch」を作成するときに取得して保存する必要がある場合を除きます。 – cklab

関連する問題