2009-07-09 1 views
1

필자는 클래스에 Entity (클래스)를 키로, 역할 (열거 형)을 값으로 갖는다. (열거를 역할이다)이이 클래스IDictionary를 저장하는 NHibernate : TransientObjectException

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

은 다음과 같습니다 : 새로운 인스턴스를 저장하려고하면 IDictionary가 나는 다음과 같은 오류가 엔터티의 새로운 인스턴스로 가득 케이스,의 (비 지속)

다음과 같이
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> 

샘플 다음 testcode에서

[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 */ 
} 

는 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 메서드가 있습니다. 해당 저장 메서드에서 지정된 사례의 모든 엔터티를 반복하고 각 엔터티에 대해 'SaveOrUpdate'를 명시 적으로 호출 할 수 있습니다.

왜이 문제에 대해 사전을 사용하고 있는지 궁금합니다.

+0

반전을 true로 설정하면 예외는 없지만 엔티티는 여전히 저장되지 않습니다. 실제로 Save 메소드를 사용하는 일반적인 Repository 클래스를 사용하지만, 올바르게 매핑 한 경우 NHibernate가이 작업을 수행 할 수있는 경우 추가 코드를 작성하고 싶지 않습니다. 내가 다른 선택의 여지가 없다면 아마도 이것은 내가해야 할 일일 것입니다. 각 사례에 대해 동일한 엔터티를 한 번만 저장하기를 원했기 때문에 사전을 사용합니다 (이것이 내가 키로 사용하는 이유입니다). 그리고 하나의 엔티티에 많은 역할이있는 경우 Flags-enum을 사용할 수 있습니다. 이것이 문제가되는 경우 아마도 솔루션을 수정해야 할 것입니다. –