2009-07-09 9 views
1

私のクラスでは、Entity(クラス)をキーとし、Roles(enum)を値として持つIDictionaryを持っています。 IDictionaryを、エンティティの新しいインスタンスで満たされている場合の新しいインスタンスを(非永続)、保存しようとするとき、私は次のエラーを取得する:IDictionaryを保存するNHibernate:TransientObjectException

NHibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing. Type: Entity

は、これらは、クラス(役割が列挙型である)されています

public class Case 
{ 
    public Case { EntityCollection = new Dictionary<Entity, Roles>(); } 
    public virtual int Id { get; set; } 
    public virtual IDictionary<Entity, Roles> EntityCollection { get; set; } 
} 

public class Entity 
{ 
    public virtual int Id { get; set; } 
} 

とマッピングは次のとおりです。

<class name="Case" table="[Case]"> 
    <id name="Id" column="Id" type="Int32" unsaved-value="any"> 
     <generator class="hilo"/> 
    </id> 
    <map name="EntityCollection" table="CaseEntityRoles" 
    cascade="save-update" lazy="false" inverse="false"> 
     <key column="CaseId" /> 
     <index-many-to-many class="Entity" 
     column="EntityId" /> 
     <element column="Roles" type="Roles" not-null="true" /> 
    </map> 
</class> 

<class name="Entity" table="[Entity]"> 
    <id name="Id" column="Id" type="Int32" unsaved-value="0"> 
     <generator class="hilo"/> 
    </id> 
</class> 

テストコードのサンプル:

[Test] 
public void Can_add_new_case() 
{ 
    var newCase = new Case(); 
    newCase.EntityCollection.Add(new Entity(), Roles.Role1); 
    newCase.EntityCollection.Add(new Entity(), Roles.Role2); 

    /* At which point I try to persist newCase and get an exception */ 
} 

testcode newCaseインスタンスに永続が、新しいエンティティはありませんされています。私は< version>タグをEntityに追加し、保存されていない値を混乱させるなど、さまざまなことを試しましたが、何も役立たないようです。マッピングからわかるように、私はカスケード= "save-update"を持っています。 アイデア

答えて

1

ケースを永続化しようとする前に、まずケースによって参照されるEntityオブジェクトを永続化する必要があると思います。私はこのような問題を解決しました。たとえば、RhinoのNHRepositoryを使用する場合:

[Test] 
public void Can_add_new_case() 
{ 
    var newCase = new Case(); 
    var entity1 = new Entity(); 
    var entity2 = new Entity(); 
    newCase.EntityCollection.Add(entity1, Roles.Role1); 
    newCase.EntityCollection.Add(entity2, Roles.Role2); 

    Rhino.Commons.NHRepository<Entity> entityRepository = new NHRepository<Entity>(); 
    Rhino.Commons.NHRepository<Case> caseRepository = new NHRepository<Case>(); 

    using (UnitOfWork.Start()) 
    { 
     entityRepository.SaveOrUpdate(entity1); 
     entityRepository.SaveOrUpdate(entity2); 
     caseRepository.SaveOrUpdate(newCase); 
    } 
} 
+1

はい、これは私がやったこととほぼ同じです。 NHibernateが自動的に処理しないことは残念です。誰かが他の解決策を知っている場合(あるいはこのバグがバグであれば修正予定)は教えてください。しかしそれまでは、これを必要な解決策として受け入れる必要があります。 –

0

inverseをtrueに設定するとどうなりますか?私は、これはあなたの問題を解決ウィルかどうか知らない

は...

あなたが何ができるか

、リポジトリパターンを利用して、そして「CaseRepository」クラスを作成することです。 そのリポジトリには、指定されたケースを保存するSaveメソッドがあります。 この保存メソッドでは、指定されたCaseのすべてのエンティティをループし、明示的に 'SaveOrUpdate'を各エンティティに対して呼び出すことができます。

また、なぜこの問題で辞書を使用しているのだろうか?

+0

逆をtrueに設定すると例外はなくなりますが、エンティティはまだ保存されません。私は実際にはSaveメソッドで汎用リポジトリクラスを使用していますが、NHibernateがそれを正しくマップしてくれれば、これに対して余分なコードを書いたくありませんでした。私に他の選択肢がなければ、これはおそらく私がやらなければならないことでしょう。 私は辞書を使用しています。なぜなら、それぞれのケースに対して同じエンティティを1回だけ保存したかったからです(これがキーとして使用する理由です)。そのアイデアは、あるエンティティに多くの役割がある場合、私はただFlags-enumを使うことができるということでした。これが問題になる場合は、おそらく私の解決策を修正する必要があります。 –

関連する問題