2010-05-09 3 views
3

다음과 같은 Nhibernate 문제로 하루 종일 책상에서 머리를 숙이고 있습니다.Nhibernate 자식 개체 삽입 오류로 일대일 매핑 문제가 발생했습니다.

각 은행 계좌에는 관련된 요금이 하나뿐입니다. 은행 계좌 테이블의 기본 키인 BankAccountID는 외래 키이고 AccountRate 테이블의 기본 키입니다.

public class BankAccount 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual string AccountName { get; set;} 
    public virtual AccountRate AccountRate {get;set;} 
} 

public class AccountRate 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual decimal Rate1 { get; set; } 
    public virtual decimal Rate2 { get; set; } 
} 

내가는 BankAccount에 대해 다음 HBM 매핑이 있습니다

<class name="BankAccount" table="BankAccount"> 
<id name ="BankAccountId" column="BankAccountId"> 
    <generator class="foreign"> 
    <param name="property"> 
     AccountRate 
    </param> 
    </generator> 
</id> 
<property name ="AccountName" column="AccountName" /> 
<one-to-one name="AccountRate" class="AccountRate" constrained="true" cascade="save-update"/> 
</class> 

과 AccountRate에 대해 다음 :

<class name="AccountRate" table="AccountRate"> 
<id name ="BankAccountId" column="BankAccountId"> 
    <generator class="native" /> 
</id> 
<property name ="Rate1" column="Rate1" /> 
<property name ="Rate2" column="Rate2" /> 
</class> 

기존 BankAccount가 객체가 문제없이 데이터베이스에서 읽을 수 있습니다. 그러나 새 BankAccount가 만들어지면 insert 문이 실패합니다.

Cannot insert the value NULL into column 'BankAccountId' 

하위 개체 인 AccountRate가 먼저 생성 된 것으로 보입니다. 부모로부터 식별자를 아직받지 못하기 때문에 삽입이 실패합니다.

BankAccount의 AccountRate 속성이 다음과 같은 컬렉션을 사용할 수 있다고 말하는 것이 맞다고 생각하십니까?

Inverse=True 

부모를 먼저 삽입해야합니다.

아무도 도와 줄 수 있습니까? 난 정말 컬렉션을 사용하고 싶지 않아, 단 하나의 테이블 사이에 일대일 관계가 있습니다.

감사

바울이 주위

답변

5

좋아, 문제를 해결했다고 생각합니다. 내 문제는 공유 기본 키 값과 일대일로 일컬어지는 것으로 보입니다. 대답은 좋은 밤 잠에 의해 발견되었고 'Nhibernate in Action'의 192-193 페이지를 참조하십시오.

처음에는 수정이 필요한 많은 오류가있었습니다. 이렇게하면 클래스와 HBM 파일을 모두 수정해야합니다.

먼저 각 클래스는 다른 클래스 유형의 속성을 포함해야하므로 AccountRate 클래스에 BankAccount 속성을 추가해야했습니다.

public class BankAccount 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual string AccountName { get; set;} 
    public virtual AccountRate AccountRate {get;set;} 
} 

public class AccountRate 
{ 
    public virtual int BankAccountId { get; set; } 
    public virtual decimal Rate1 { get; set; } 
    public virtual decimal Rate2 { get; set; } 
    Public virtual BankAccount BankAccount {get;set;} 
} 

또한 BankAccount HBM 파일에서 오류가 발생했습니다. 발전기 클래스를 외국으로 설정해서는 안됩니다. AccountRate 클래스에 있어야합니다. 제약 조건 또한 일대일 연계에서 제거해야했습니다. 새로운 BankAccount HBM 파일은 다음과 같습니다.

<class name="BankAccount" table="BankAccount"> 
<id name ="BankAccountId" column="BankAccountId"> 
    <generator class="native"> 
</id> 
<property name ="AccountName" column="AccountName" /> 
<one-to-one name="AccountRate" class="AccountRate" cascade="all"/> 
</class> 

옆 AccountRate HBM 외국 설정 generator 클래스를 필요로하고, "일대일"태그 클래스 간의 관계를 완료했다.

<class name="AccountRate" table="AccountRate">   
<id name ="BankAccountId" column="BankAccountId">   
    <generator class="foreign"> 
     <param name="property">BankAccount</param> 
    </generator>   
</id>   
<property name ="Rate1" column="Rate1" />   
<property name ="Rate2" column="Rate2" /> 
<one-to-one name="BankAccount" class="BankAccount" constrained="true" />  
</class> 

이 문제를 조사한 모든 사람들에게 감사드립니다. 나는 그것이 모두 곡선의 일부라고 생각합니다.

+0

예상대로 작동하는지 확인하십시오. – Darius

0

한 빠른 방법은 BankAccountId의 널 (NULL)을하는 것입니다. NHibernate는 null id를 가진 BankAccount 테이블에 레코드를 삽입하고 id를 업데이트해야한다.

이전에는 null 대신 올바른 ID를 사용하여 초기 삽입 작업을 수행하는 방법을 발견했습니다. 불행히도, 나는 내 삶이 내가 바꾼 것을 기억할 수는 없다.

관련 문제