2010-05-18 2 views
0

우리는 nhibernate가있는 오래된 asp.net 응용 프로그램을 확장하고 일부를 업그레이드합니다. 사용 된 NHibernate는 꽤 오래되었습니다 (1.0.2.0), 우리는 새로운 기능을 (2.1.2)로 업그레이드하기로 결정했습니다. HBM 파일은 MyGeneration이있는 사용자 정의 템플릿을 통해 생성됩니다. 한 가지를 제외하고는 모든 것이 아주 부드럽게 진행되었습니다.Nhibernate 1.0.2.0에서 2.1.2 로의 마이그레이션과 다 대일 저장 문제

우리는 개체 블로그와 게시물이 필요합니다. 블로그에는 여러 개의 게시물이있을 수 있으므로 게시물은 다 대일 관계를 유지합니다. 이 응용 프로그램이 작동하는 방식으로 인해 관계는 기본 키가 아닌 Blog.Reference 열을 통해 수행됩니다.

샘플 mapings 및 .cs 파일 :

<?xml version="1.0" encoding="utf-8" ?> 

<id name="Id" column="Id" type="Guid"> 
     <generator class="assigned"/> 
    </id> 
    <property column="Reference" type="Int32" name="Reference" not-null="true" /> 
    <property column="Name" type="String" name="Name" length="250" /> 
</class> 

<?xml version="1.0" encoding="utf-8" ?> 

<id name="Id" column="Id" type="Guid"> 
     <generator class="assigned"/> 
    </id> 

    <property column="Reference" type="Int32" name="Reference" not-null="true" /> 
    <property column="Name" type="String" name="Name" length="250" /> 
    <many-to-one name="Blog" column="BlogId" class="SampleNamespace.BlogEntity,SampleNamespace" property-ref="Reference" /> 
</class> 
,451,515,

그리고 클래스 파일

class BlogEntity 
{ 
    public Guid Id { get; set; } 
    public int Reference { get; set; } 
    public string Name { get; set; } 
} 

class PostEntity 
{ 
    public Guid Id { get; set; } 
    public int Reference { get; set; } 
    public string Name { get; set; } 
    public BlogEntity Blog { get; set; } 
} 

이제이었다 내가 아이디 1D270C7B-090D-47E2-8CC5-A3D145838D9C와 오래된 NHibernate에 같은 것은 참고 1

와 블로그를 가지고 있다고 할 수 있습니다 가능 :

 //this Blog already exists in database 
     BlogEntity blog = new BlogEntity(); 
     blog.Id = Guid.Empty; 
     blog.Reference = 1; //Reference is unique, so we can distinguish Blog by this field 
     blog.Name = "My blog"; 

     //this is new Post, that we are trying to insert 
     PostEntity post = new PostEntity(); 
     post.Id = Guid.NewGuid(); 
     post.Name = "New post"; 
     post.Reference = 1234; 
     post.Blog = blog; 

     session.Save(post); 

그러나 새 버전에서는 Post.BlogId에 NULL을 삽입 할 수없는 예외가 발생합니다. 이전 버전에서는 nhibernate에 대해 Blog.Reference 필드가 있으면 충분했으며 해당 필드로 엔티티를 검색하여 PostEntity에 첨부 할 수 있었고 PostEntity를 저장하면 모든 것이 올바르게 작동합니다. 그리고 내가 이해하는 바와 같이, 새로운 NHibernate는 Blog.Id 만 검색하려고 시도합니다.

해결 방법? DB 디자인을 변경할 수 없으며 BlogEntity에 객체를 할당 할 수 없습니다. 객체가 내 제어에서 벗어 났으므로 (외부 소스에서 이와 같이 일반 "ojbects"로 미리 채워짐)

답변

0

코드에 매우 이상하게 보입니다.

var criteria = DetachedCriteria.For<Blog>(); 
criteria.Add(Expression.Eq("Reference", 1)); 
var blog = criteria.GetExecutableCriteria(session).List<Blog>().FirstOrDefault(); 

post.Blog = blog; 
session.Save(post); 
+0

불행히도 저는 이렇게 할 수 없습니다. 말하자면 나는 50 가지 이상의 다른 객체를 가지고 있으며, 구식의 "generic"메소드를 통해 들어온다. InsertEntity (객체 엔티티)라고 할 수있다. 엔티티는 블로그 일 수도 있고 포스트 일 수도 있고 사용자 일 수도 있고 다른 일일 수도 있습니다 ... 그리고 최악의 부분 - 그 방법을 바꿀 수는 없기 때문에 내 통제가 불가능합니다. – Meska

+0

나는 왜 아직도 당신이 이해할 수 없는지 이해하지 못합니다. 해. 세션이 있습니다. 원본 코드에서 저장 (게시)하십시오. 이는 코드에서 다를 수 있습니다. 그리고 내가 추가 한 코드는 참조로 Blog 엔티티를 조회하는 쿼리 만 수행합니다. 문제가 정확히 무엇입니까? 문제가 코드를 변경할 수 없다면 새로운 NHibernate 라이브러리를 도입하지 말 것을 제안합니다. –

+0

이 블로그/포스트 시나리오는 실제 상황을 증명하는 것일뿐입니다. 훨씬 더 복잡하고 save 메서드는 다음과 같습니다. InserEntity (개체 엔터티) { // 일부 처리를 수행합니다. 엔티티가 실제로 일반입니다. session.save } 저는 InserEntity (객체 엔티티)의 서명을 변경할 수 없습니다. 아무튼, 도움 주셔서 감사합니다 :) 그리고 그것은 몇 일 안에 실현 가능한 해결책이 없다면 우리는 새로운 nhibernate의 도입을 건너 뛸 것으로 보입니다. – Meska

0

blog.Id = Guid.Empty 

은 다음과 같이 번역된다, NH 1에 근무하지만 어쨌든 순간에 작동하지 않기 때문에, 나는 당신이 먼저 쿼리의 블로그 실체를 찾기 위해 생각 DB에 null이있다. 따라서 샘플 코드에서와 같이 변경하면 BlogEntity Id에 null 값을 명시 적으로 설정합니다.

이것은 수신하는 오류이며 "참조"열/속성과 관련이 없습니다.

당신이 할 수있는 것에 관해서 ... 물론 당신은 GUID에 ORM 조인을 할 필요가 없습니다! 참조 열에 조인을 만들 수 있습니다 ...

+0

그러나 1.0.2.0에서 어떻게 작동 했나요? ORM이 참조에 조인을하는 것에 대해 더 설명해 주시겠습니까? 모든 키워드 그래서 나는 더 많은 정보를 구글 수 있습니까? 감사합니다 – Meska

+0

저는 1.2에서 2 ++와 많은 차이점을 발견했습니다. 대부분의 경우 2 + + 버전이 규칙에 훨씬 엄격합니다. 이제는 조인 (join)에 관해서, DB PK를 가졌다 고해서 실제로 매핑을해야한다는 것을 의미하지는 않습니다. 엔티티의 ID로 Reference 열을 매핑 할 수 있지만 많은 테스트를하고 실제 Guid PK가 항상 삽입되는지 확인해야합니다.이 문제는 나쁜 db 스키마에서 파생되므로 NHibernate가 자동으로 실행되도록 기대하지 마십시오. 마술처럼 당신을 위해 그것을 해결하십시오. – Jaguar

0

내 질문에 답합니다.

문제는 nhibernate가 DBE를 검색하여 ID 00000000-0000-0000-0000-000000000000 인 BlogEntity를 검색하는 것이 었습니다. 물론 DB에 그것은 아무것도 없어, 그래서 널

를 삽입하려 그리고 그것은 BlogEntity 경우 할당 된 식별자를 확인할 수 없습니다

일어나는 이유를 명확 로그에 표시했다 00000000-0000-0000 -0000-000000000000 은 일시적이거나 분리되어 있습니다. 데이터베이스를 쿼리합니다. 이를 방지하려면 세션에서 명시 적 Save() 또는 Update()를 사용하십시오.

는 내 세션에 전달하고 특히 방법 bool? IsTransient(object entity)

그리고 문제 해결, IInterceptor을 구현 해결.

관련 문제