2011-12-17 2 views
1

데이터베이스의 두 테이블간에 식별 관계가 있습니다.HasOne 관계를 확인하지 않음

상위 테이블에는 ID를 통해 생성되는 기본 키가 있습니다. 하위 테이블에는 상위 테이블의 ID 생성 기본 키인 기본 키가 있습니다. 그것은 진정한 일대일입니다.

나는 모든 종류의 결과와 함께 여러 맵핑 전략을 시도했지만 그 중 아무 것도 완벽하지 않았습니다.

부모 매핑 파일이있다합니다 (Cascade.All을 (통지) - 나는 부모의 관계를 관리 할 것으로 예상) :

Id(Reveal.Member<ChildObject>("ID")) 
.GeneratedBy.Foreign("ParentObject"); 
HasOne(Reveal.Member<ChildObject, ParentObject>("ParentObject")) 
.Constrained() 
.ForeignKey(); 

I :

HasOne(x => x.ChildObject).Cascade.All(); 

아이 매핑이있다 무고한 사람을 보호하기 위해 객체 이름을 변경했습니다.

그래서 어떻게 될까요? 나는 부모의 인스턴스를 만들고, 나는 자식의 인스턴스를 만들고 관계를 설정한다. (자식을 부모에 추가하고 부모를 자식에 추가한다.)

나는이 코드를 실행 :

session.SaveOrUpdate(_Parent); 
session.Clear(); 
transaction.Commit(); 

은 내가 일어날 것으로 예상하면 ID가 데이터베이스에서 부모 업데이트되면서, 부모가 저장됩니다이다. 그런 다음 ID를 하위에 설정하고 하위를 저장해야합니다.

대신 부모는 저장되지만 자식은 저장되지 않습니다. nHibernate가 실행중인 삽입 문을 볼 수 있으며 자식 개체는 데이터베이스에 표시되지 않습니다.

하위 (상위에서 하위로 올바르게 전파 됨)의 부모로부터 ID가 있지만 nHibernate는 하위를 더티 (내 부분의 추측)로 인식하지 않습니다. Child 객체에서 SaveOrUpdate를 명시 적으로 시도하더라도 저장되지 않습니다.

그러나 조금 더 이상합니다. Child에 더티 객체 컬렉션을 첨부하고 Child에 SaveOrUpdate 을 명시 적으로이라고 호출하면 nHhiberante는 Child 및 컬렉션을 예상 한 동작을 유지합니다. 하지만 여전히 명시 적으로 호출해야합니다.

부모 - 자녀 관계를 매핑하는 데 실수가 있습니까?

답변

1

제 생각 엔 parent.Id는 신원에 의해 생성됩니다.

라인 session.SaveOrUpdate(_Parent);은 부모를 저장하여 ID를 가져오고 커밋 할 때 플러시하도록 하위의 삽입을 캐시합니다. session.Clear(); 그러면 캐싱 된 인서트가 제거되고 transaction.Commit(); 할 일이 없습니다.

+0

감사합니다. Firo - 그 대답이었습니다. nHibernate가 트랜잭션이 커밋 될 때까지 자식 객체가 아닌 부모 객체를 저장하는 이유를 이해할 수 없습니다. 그것은 마치 외관과 같습니다. 나는 그것이 성과 이익이라고 생각한다. 어쨌든 훌륭한 답변에 감사드립니다. –

+0

예 모든 인서트가 하나의 왕복 여행으로 전송되기 때문에 성능이 향상됩니다. 단, NH가 ID를 가져 오기 위해 NH를 삽입해야하는 ID는 예외입니다 – Firo