NHibernate Session.Flush() 업데이트가 발생하지 않을 때 업데이트 쿼리 보내기

StackOverflow https://stackoverflow.com/questions/34852

  •  09-06-2019
  •  | 
  •  

문제

NHibernate 세션이 있습니다.이 세션에서는 정확히 1개의 작업을 수행합니다. 즉, 이 코드를 실행하여 목록을 가져오는 것입니다.

public IList<Customer> GetCustomerByFirstName(string customerFirstName)
{
return _session.CreateCriteria(typeof(Customer))
    .Add(new NHibernate.Expression.EqExpression("FirstName", customerFirstName))
    .List<Customer>();
}

난 전화하고있어 Session.Flush() 의 끝에서 HttpRequest, 그리고 나는 HibernateAdoException.NHibernate가 업데이트 문을 db에 전달하고 외래 키 위반을 일으키고 있습니다.내가 실행하지 않으면 flush, 요청이 문제 없이 완료됩니다.여기서 문제는 이 코드가 다른 영역에서 재사용되기 때문에 다른 세션 내에서 변경이 발생하는 경우 플러시가 필요하다는 것입니다.누락되었을 수 있는 다른 구성 설정이 있습니까?


예외의 코드는 다음과 같습니다.

[SQL: UPDATE CUSTOMER SET first_name = ?, last_name = ?, strategy_code_1 = ?, strategy_code_2 = ?, strategy_code_3 = ?, dts_import = ?, account_cycle_code = ?, bucket = ?, collector_code = ?, days_delinquent_count = ?, external_status_code = ?, principal_balance_amount = ?, total_min_pay_due = ?, current_balance = ?, amount_delinquent = ?, current_min_pay_due = ?, bucket_1 = ?, bucket_2 = ?, bucket_3 = ?, bucket_4 = ?, bucket_5 = ?, bucket_6 = ?, bucket_7 = ? WHERE customer_account_id = ?]

매개변수가 전달된 것으로 표시되지 않습니다.

도움이 되었습니까?

해결책

내 모델 중 하나가 올바르게 매핑되지 않았을 때(널 입력 가능 유형을 올바르게 사용하지 않았을 때) 이것을 한 번 본 적이 있습니다.모델과 매핑을 붙여넣을 수 있나요?

다른 팁

NHibernate를 다룰 때마다 NULL 가능 필드에 항상 주의하십시오.필드가 DB에서 NULL을 허용하는 경우 해당 .NET 클래스도 Nullable 유형을 사용하는지 확인하세요.그렇지 않으면 온갖 이상한 일들이 일어날 것입니다.증상은 일반적으로 데이터베이스에서 엔터티를 읽은 이후 어떤 필드도 변경하지 않았음에도 불구하고 NHibernate가 DB의 레코드를 업데이트하려고 시도한다는 것입니다.

다음 순서는 이러한 일이 발생하는 이유를 설명합니다.

  1. NHibernate는 ADO.NET을 사용하여 DB에서 원시 엔터티의 데이터를 검색합니다.
  2. Hibernate는 엔터티를 구성하고 그 속성을 설정합니다.
  3. DB 필드에 NULL이 포함된 경우 속성은 해당 유형의 기본 값으로 설정됩니다.
    • 참조 유형의 속성은 null로 설정됩니다.
    • 정수 및 부동 소수점 유형의 속성은 0으로 설정됩니다.
    • 부울 유형의 속성은 false로 설정됩니다.
    • DateTime 유형의 속성은 DateTime.MinValue로 설정됩니다.
    • 등.
  4. 이제 트랜잭션이 커밋되면 NHibernate는 속성 값을 DB에서 읽은 원래 필드 값과 비교하고 필드에는 NULL이 포함되어 있지만 속성에는 null이 아닌 값이 포함되어 있으므로 NHibernate는 속성이 더러운 것으로 간주하고 엔터티를 강제로 업데이트합니다.

이로 인해 성능이 저하될 뿐만 아니라(엔터티를 검색할 때마다 DB에 대한 추가 왕복 및 추가 업데이트가 발생함) DateTime 열의 오류를 해결하기 어려울 수도 있습니다.실제로 DateTime 속성이 기본값으로 초기화되면 1/1/0001로 설정됩니다.이 값이 DB에 저장되면 가능한 가장 작은 SqlDateTime은 1/1/1753이므로 ADO.NET의 SqlClient는 이를 유효한 SqlDateTime 값으로 변환할 수 없습니다!!!

가장 쉬운 해결 방법은 클래스 속성에서 Nullable 유형(이 경우 "DateTime?")을 사용하도록 만드는 것입니다.또는 DbNull.Value를 값 형식의 기본값과 적절하게 비교하는 Equals 메서드로 IUserType을 구현하여 사용자 지정 형식 매퍼를 구현할 수 있습니다.우리의 경우 Equals는 1/1/0001을 DbNull.Value와 비교할 때 true를 반환해야 합니다.완전한 기능을 갖춘 IUserType을 구현하는 것은 실제로 그렇게 어렵지는 않지만 NHibernate 상식에 대한 지식이 필요하므로 그런 식으로 진행하기로 선택한 경우 상당한 인터넷 검색을 수행할 준비를 하십시오.

나는 또한 NH 2.0.1에서 access="noop"를 사용하여 다대다 백의 반대쪽 끝을 숨기려고 할 때 이 문제를 경험했습니다(힌트:이것은 작동하지 않습니다).

access="field" 로 변환하고 클래스에 필드를 추가하면 문제가 해결되었습니다.하지만 그들을 추적하는 것은 꽤 어렵습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top