2009-07-16 5 views
1

어떻게 든 GenericADOException (제약 조건 예외)을 유발 한 객체를 얻을 수 있습니까?NHibernate/Castle activerecord : 데이터베이스 예외의 원인이 된 객체를 얻는 방법?

또는 하나의 객체 만 플러시하면 어떻게 문제가 있는지 알 수 있습니다.

양식에 표시되고 편집 및 추가 할 수있는 개체 목록이 있습니다. 플러시에서는 데이터베이스 예외가 발생하지만 어떤 객체가 예외를 발생 시켰는지 알 수 없습니다.

제한을 nhibernate로 이동할 수 없습니다.

답변

0

, 다음 NHibernate에 소스를 읽고 난 다음에 도착 :

http://fabiomaulo.blogspot.com/2009/06/improving-ado-exception-management-in.html


'http://fabiomaulo.blogspot.com/2009/06/improving-ado-exception-management-in.html 
'properties.Add("sql_exception_converter", "SmartCore.SmartDatabaseExceptionConverter, SmartCore") 
Class SmartDatabaseExceptionConverter 
    Implements ISQLExceptionConverter 


    Public Function Convert(ByVal sqlException As System.Exception, ByVal message As String, ByVal sql As NHibernate.SqlCommand.SqlString) As NHibernate.ADOException Implements NHibernate.Exceptions.ISQLExceptionConverter.Convert 

     Dim sqle As DbException 
     sqle = ADOExceptionHelper.ExtractDbException(sqlException) 
     '"could not update: [SmartCore.GL.Glaccount#1225]" 
     Dim obname As String 
     Dim key As String 
     obname = ExtractUsingTemplate("could not update: [", "#", message) 
     key = ExtractUsingTemplate("#", "]", message) 

     Dim prikey As Integer 
     prikey = Integer.Parse(key) 

     sqle.Data.Add("obname", obname) 
     sqle.Data.Add("prikey", key) 

     If sqle.ErrorCode = 335544558 Then 
      '"Operation violates CHECK constraint C_GLACCOUNT on view or table GLACCOUNT At trigger 'CHECK_56'" 
      Dim checkname As String 
      checkname = ExtractUsingTemplate("Operation violates CHECK constraint ", "on view or table ", sqle.Message) 
      Return New SmartDatabaseConstraintException(message, sqle, obname, prikey, checkname) 
      'Return New ConstraintViolationException(message, sqle, sql, checkname) 
     End If 

     Return SQLStateConverter.HandledNonSpecificException(sqlException, message, sql) 
    End Function 



    Protected Function ExtractUsingTemplate(ByVal templateStart As String, ByVal templateEnd As String, ByVal message As String) As String 
     Dim templateStartPosition As Integer = message.IndexOf(templateStart) 
     If templateStartPosition < 0 Then 
      Return Nothing 
     End If 

     Dim start As Integer = templateStartPosition + templateStart.Length 
     Dim [end] As Integer = message.IndexOf(templateEnd, start) 
     If [end] < 0 Then 
      [end] = message.Length 
     End If 

     Return message.Substring(start, [end] - start).Trim() 

    End Function 
End Class 

'USAGE 
     Try 
      _scope.Flush() 
     Catch ex As SmartDatabaseConstraintException 
      If ex.ConstraintName = "C_GLACCOUNT" Then 
       Dim gla As GL.Glaccount 
       gla = GL.Glaccount.Find(ex.EntityId) 'should be fast from entity cache 
       msgboxError(gla.description & " is duplicate please rename") 
      Else 
       msgboxError(ex.Message) 
      End If 
     End Try 

나는 그것을 작업하기 위해 적응해야했습니다. 내 약간 구식 nhibernate 버전 (3 월에서 2.1) 나는 하나의 개체 이름과 ID를 얻을 수있는 AdoExceptionContextInfo있는 최신 버전에서 작동하도록 위의 약간 적응해야합니다. Nhibernate가 좋다!

0

NHibernate Profiler를 사용해 보셨습니까? 어느 것이 문제인지에 대한 추가 세부 정보를 제공해야합니다. 내가 도움이되었다 게시물에 도착 일부 인터넷 검색으로

+0

나는 눈알이 어느 것이 문제를 일으키는 지 알고 있으며 문제는 그것을 코드로 결정하는 방법입니다. 내가 코드를 수정하거나 삭제할 수 있도록 개체가 문제를주는 알고 있어야합니다. 데이터베이스의 고유 한 제약 조건을 생각해보십시오. – AngelBlaZe

+0

제 이해는 NHibernate가 꽤 확장 가능하고 당신이 NH에서이 정보를 얻을 가능성이 높습니다. 이 시점에서 두 가지 옵션이 있습니다. 1. Ayende Rahien과 같은 전문가가 나타나기를 바랍니다 (의심 스러울 때 - 그를 고용 할 가능성이 더 큽니다) 2.이 작업을 단일 작업 단위로 취급해야하므로 각 업데이트에 대해 수동으로 플러시하는 것이 나에게 가능성이있는 옵션 인 것 같습니다. –

+0

하나의 객체를 수동으로 플러시하는 방법을 알고 있습니까? 세션에서이 객체 만 플러시하도록 지시하는 것과 같습니다. 나는 그 (것)들의 명부가 있고 창 모양에 databinding에 의해 변화되고있다, 그래서 나는 웹에서 사람이 할 수있는 때 그들이 언제 변화하는지 아무 통제도 없다. – AngelBlaZe

관련 문제